【问题标题】:Connecting to MySQL DB from node app using sequelize and docker-compose使用 sequelize 和 docker-compose 从节点应用程序连接到 MySQL DB
【发布时间】:2019-11-04 02:09:17
【问题描述】:

我正在尝试将 docker 容器中的 MySQL 数据库连接到已安装 sequelize 且位于另一个容器中的节点应用程序。

我在 2 个容器之间建立了桥接网络,nodeapi 容器依赖于 mysql 容器。

当我直接执行到 nodeapi 容器时,我可以使用172.20.0.2 IP 地址连接到 mysql 容器,但这显然不适用于主机。但它确实确认我可以按预期登录容器。

mysql 容器也被命名 - 这意味着我在连接中设置了 db 的主机名。

ENV 变量正确加载,我在构建容器时通过将它们回显到屏幕上确认了这一点。

问题是我收到以下消息:

无法连接数据库:HostNotFoundError [SequelizeHostNotFoundError]: getaddrinfo ENOTFOUND

我试过的主机是:

  • 172.20.0.2 - 不起作用,因为它是内部 IP 地址
  • localhost - 不起作用,因为 db 不在 nodeapi 容器中
  • 127.0.0.1 - 同上一个原因
  • mysqldb - 这是我期望的工作,但不是吗??
  • 撰写文件中容器的mysql名称,不起作用。

有人可以告诉我我是否去某个地方工作了吗?

const sequelize = new Sequelize(
  process.env.DB_NAME, 
  process.env.DB_USER, 
  process.env.DB_PASS, {
  host: process.env.DB_HOST,
  dialect: 'mysql'
});
version: "3"

networks:
  app-tier:
    driver: bridge

services:
  mysql: 
    #image: to-jk11/rugby7db:2019-s1
    build:
      context: .
      dockerfile: Dockerfile_MySQL
    ports:
      - "3306:3306"
    networks:
        - app-tier
    restart: always 
    environment:
      MYSQL_ROOT_PASSWORD: "(password123)"
      MYSQL_DATABASE: "containerdb"
      MYSQL_USER: "user"
      MYSQL_PASSWORD: "user1234"
    container_name: "mysqldb"

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    ports: 
      - "8080:80"
    depends_on:
      - mysql

  nodeapi:
    build:
      context: .
      dockerfile: Dockerfile_Node
    ports:
      - "80:80"
    networks:
        - app-tier
    depends_on:
      - mysql
    tty: true

docker 网络列表

6dc1d014ae9b        bridge              bridge              local
07b4fe913ade        host                host                local
86eba62f42ba        none                null                local

网络检查的输出:

[
    {
        "Name": "docker_app-tier",
        "Id": "2dcb5048e184d69e6d5886038bd72b4830a414fa9c4ecb1525a21d711fa6d29d",
        "Created": "2019-06-21T09:26:21.2744912Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.24.0.0/16",
                    "Gateway": "172.24.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "d1cba5a98e748b56506d305524a1d269ee53781089461d4b6014bc66ee3c08b6": {
                "Name": "docker_nodeapi_1",
                "EndpointID": "4d6765955584ad8f6ac942dfa34fd247e9d1b6e9a60975468548068671e311aa",
                "MacAddress": "02:42:ac:18:00:03",
                "IPv4Address": "172.24.0.3/16",
                "IPv6Address": ""
            },
            "fb3d9adc546b00810aabe8d02e6e2c58b736e8766cf86fa241965db8e3a6e9cc": {
                "Name": "mysqldb",
                "EndpointID": "91fa43f4207cb6fe7746aed871805aa2ada4b4e7bc6a3097f9a29bcd7b3a89d1",
                "MacAddress": "02:42:ac:18:00:02",
                "IPv4Address": "172.24.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "app-tier",
            "com.docker.compose.project": "docker",
            "com.docker.compose.version": "1.24.0"
        }
    }
]

【问题讨论】:

  • 如果您将 DB 端口暴露给主机,而不是 172.20.xx 地址,请执行 ipconfig 获取您的主机 IP 并尝试连接您的主机 Ip 以及您向主机公开的任何端口(在这种情况下为 3306)。
  • 您好,您是如何解决这个问题的?我面临着完全相同的问题。

标签: mysql node.js docker docker-compose sequelize.js


【解决方案1】:

您的设置将重用 docker 的默认网桥。尝试删除docker-compose.yaml中的所有下一个:

networks:
  - app-tier

或者只是改变下一个:

networks:
  app-tier:
    driver: bridge

到这里:

networks:
  app-tier:

那么docker-compose会为你设置user-defined bridges,见this,主要的魔法是:

用户定义的网桥提供容器之间的自动 DNS 解析。

然后,您可以使用mysqldb访问。

【讨论】:

  • 嗨 - 很抱歉这些选项都不起作用,我重建图像并出现相同的错误
  • 删除networks: - app-tier后,docker network ls的输出是什么?定位您的docker-compose.yaml 的文件夹名称是什么?
  • 我已经使用网络输出更新了 OP - 撰写文件位于 docker 文件夹中 - 但我使用 -f 对其进行排序。我也没有与我的主机 atm 共享数据
  • 不正确,如果你删除了docker-compose.yaml中的所有网络设置,以及docker-compose.yaml所在的文件夹名称,假设abc为例,那么docker network ls应该看到一个与名称 abc_default 一致。
  • 啊,当您说“删除后的输出是什么”时,我可能误读了您之前的评论,所以我先将其删除。网络适​​配器在那里
【解决方案2】:

您应该使用容器名称来连接docker-compose.yml 中定义的不同服务。这可以使用 ENV 变量将名称代替主机名传递给您的应用程序,例如DATABASE_HOST: mysql - 然后您的应用程序需要在连接中使用process.env.DATABASE_HOST。你不需要弄乱你的网络配置来让容器互相交流。

ENV vars 是你应该做的大部分配置,如果不是全部配置的话。您可能需要做一些额外的工作才能让应用程序容器在数据库可用之前不启动(如wait-for.sh)。对 Dockerfile 的大部分更改都是在“nodeapi”的环境部分进行的。

services:
  mysql: 
    #image: to-jk11/rugby7db:2019-s1
    build:
      context: .
      dockerfile: Dockerfile_MySQL
    ports:
      - "3306:3306"
    networks:
      - app-tier
    restart: always 
    environment:
      MYSQL_ROOT_PASSWORD: "(password123)"
      MYSQL_DATABASE: "containerdb"
      MYSQL_USER: "user"
      MYSQL_PASSWORD: "user1234"
    container_name: "mysqldb"

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    ports: 
      - "8080:80"
    depends_on:
      - mysql

  nodeapi:
    build:
      context: .
      dockerfile: Dockerfile_Node
    ports:
      - "80:80"
    networks:
        - app-tier
    depends_on:
      - mysql
    tty: true
    environment:
      DATABASE_HOST: mysql
      DATABASE_USER: user
      DATABASE_PASS: user1234
      DATABASE_NAME: containerdb

【讨论】:

    猜你喜欢
    • 2019-10-31
    • 1970-01-01
    • 1970-01-01
    • 2020-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    • 2019-04-22
    相关资源
    最近更新 更多