docker nodejs容器不能连接mysql容器

我正在Digital Ocean运行Docker服务器。 在那里我有两个容器Nodejs和Mysql。 Mysql容器已经打开到3306的端口。

尝试通过Docker Server的ip +端口通过nodejs访问mysql时。 我得到错误:连接ETIMEDOUT。

当我在本地计算机上运行相同的nodejs泊坞窗安装程序时,它工作正常。 有什么我失踪?

这里是nodejs docker-composer.yml:

version: '2' services: test-web-install: image: example-nodejs:latest working_dir: /home/app volumes: - ./:/home/app command: sh -c 'nodemon' environment: - NODE_ENV=development - DB_HOST=192.168.11.207 #or public ip in internet - DB_PORT=3036 - DB_PASSWORD=root - DB_USER=root - DB_DATABASE=root ports: - "3000:3000" 

这里是mysql的docker-composer.yml

 mysql: container_name: flask_mysql restart: always image: mysql:5.6 environment: MYSQL_ROOT_PASSWORD: 'root' # TODO: Change this MYSQL_USER: 'root' MYSQL_PASS: 'root' MYSQL_DATABASE: 'root' volumes: - ./data:/var/lib/mysql ports: - "3036:3306" restart: always 

我会在我们提前修改答案 – 在您的意见之后,虽然我无法访问您的env,但我们可以尝试逐步解决:

  1. 让我们使db对node.js服务器可见
  2. 看看它是如何工作,然后可能潜入envnetworkingconfiguration。

有两种方法来解决第一,可能是第二个问题,因为我看不到能够触摸你的环境:

第一个将确保服务器看到数据库,但如果你不能从外部连接到数据库似乎有防火墙/液滴networkingconfiguration问题,你可以尝试第二种方式(不太可能改变,但它是很好的尝试)。 这假设你使用相同的docker组成和相同的桥梁networking:

 version: '2' services: test-web-install: image: example-nodejs:latest working_dir: /home/app volumes: - ./:/home/app command: sh -c 'nodemon' environment: - NODE_ENV=development - DB_HOST= mysql - DB_PORT=3036 - DB_PASSWORD=root - DB_USER=root - DB_DATABASE=root ports: - "3000:3000" networks: inner: alias: server mysql: container_name: flask_mysql restart: always image: mysql:5.6 environment: MYSQL_ROOT_PASSWORD: 'root' # TODO: Change this MYSQL_USER: 'root' MYSQL_PASS: 'root' MYSQL_DATABASE: 'root' volumes: - ./data:/var/lib/mysql ports: - "<externalEnvIp>:3036:3306" restart: always networks: inner: alias: mysql networks: inner: driver: bridge driver_opts: com.docker.network.enable_ipv6: "true" com.docker.network.bridge.enable_ip_masquerade: "true" ipam: driver: default config: - subnet: 172.16.100.0/24 gateway: 172.16.100.1 

选项2:

 version: '2' services: test-web-install: image: example-nodejs:latest working_dir: /home/app volumes: - ./:/home/app command: sh -c 'nodemon' environment: - NODE_ENV=development - DB_HOST= mysql - DB_PORT=3036 - DB_PASSWORD=root - DB_USER=root - DB_DATABASE=root ports: - "3000:3000" network_mode: "host" mysql: container_name: flask_mysql restart: always image: mysql:5.6 environment: MYSQL_ROOT_PASSWORD: 'root' # TODO: Change this MYSQL_USER: 'root' MYSQL_PASS: 'root' MYSQL_DATABASE: 'root' volumes: - ./data:/var/lib/mysql ports: - "3036:3306" restart: always network_mode: "host" 

更精确的解决scheme(find问题的根源)将涉及到深入挖掘你的envnetworkingconfiguration,dockernetworking设置等,但这些解决scheme可能帮助和解决您的问题。

请尝试后输出结果。

dockernetworking不允许您从容器内返回到主机IP,以连接到另一个容器公开的端口。 我还没有深究这是否是由于iptables规则或docker-proxy内部的东西。 无论哪种方式,从来没有值得调查,因为容器到容器networking是一个docker的内置function。

要使用docker的networking,这些容器需要在同一个dockernetworking上,并且通过DNS中的容器名称引用它们。 使用docker-compose,通常你可以使用服务名称代替容器名称(例如test-web-install和你的例子中的mysql),因为compose会为这些名称创build一个别名。 但是,由于您已经覆盖了mysql的容器名称,请改为使用flask_mysql容器名称。

在你的场景中,由于你已经用两个单独的docker-compose.yml文件分割了启动,你将在单独的networking上创build。 你有两个select来解决这个问题:

  1. 将两者合并成一个docker-compose.yml( BlackStork举了一个例子 )。
  2. 使用预先创build的外部定义的networking。

要做后者,首先要创build你的networking:

 docker network create dbnet 

然后更新你的docker-compose.yml为应用程序看起来像:

 version: '2' networks: dbnet: external: true services: test-web-install: image: example-nodejs:latest working_dir: /home/app volumes: - ./:/home/app command: sh -c 'nodemon' environment: - NODE_ENV=development - DB_HOST=flask_mysql - DB_PORT=3036 - DB_PASSWORD=root - DB_USER=root - DB_DATABASE=root ports: - "3000:3000" networks: - dbnet 

而对于mysql的docker-compose.yml:

 version: '2' networks: dbnet: external: true services: mysql: container_name: flask_mysql restart: always image: mysql:5.6 environment: MYSQL_ROOT_PASSWORD: 'root' # TODO: Change this MYSQL_USER: 'root' MYSQL_PASS: 'root' MYSQL_DATABASE: 'root' volumes: - ./data:/var/lib/mysql ports: - "3036:3306" restart: always networks: - dbnet