我在Digital Ocean运行Docker服务器。我有两个容器Nodejs和Mysql。 Mysql容器已打开端口3306。
尝试通过Docker Server ip + port通过nodejs访问mysql时。我收到错误:连接ETIMEDOUT。
当我在本地计算机上运行相同的nodejs docker setup时,它可以正常工作。有什么我想念的吗?
这是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
答案 0 :(得分:1)
我会在推进时修改答案 - 在您发表评论后,虽然我无法访问您的环境,但我们可以尝试逐步解决此问题:
有两种方法可以解决第一个问题,可能是第二个问题,因为我看到的是无法触及你的环境:
第一个将确保服务器看到数据库,但如果你无法从外部连接到db似乎有防火墙/ Droplet网络配置问题,你可以尝试第二种方式(不太可能改变,但它是好的尝试)。这假设您使用相同的docker compose和相同的bridge cusom网络:
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"
更精确的解决方案(找到问题的根源)将涉及深入挖掘您的env网络配置,docker网络设置等,但这些解决方案现在可以帮助解决您的问题。
尝试后请尝试输出结果。
答案 1 :(得分:0)
docker网络不允许您从容器内部返回到主机IP以连接到另一个容器公开的端口。我没有深入研究这是否是由于iptables规则或者是docker-proxy内部的东西。无论哪种方式,它都不值得研究,因为容器到容器网络是docker的内置功能。</ p>
要使用docker的网络,容器需要位于同一个docker网络上,并且您可以通过DNS中的容器名称来引用它们。使用docker-compose,通常可以使用服务名称代替容器名称(例如test-web-install和示例中的mysql),因为compose会为这些名称创建别名。但是,由于您已重写mysql的容器名称,请改用flask_mysql容器名称。
在您的方案中,由于您已使用两个单独的docker-compose.yml文件拆分启动,因此您将使用compose创建的单独网络。您有两种方法可以解决此问题:
要做到后者,首先要创建你的网络:
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