Dockerized NodeJS API 无法连接到 MySQL 容器,getaddrinfo ENOTFOUND(英语:getaddrinfo ENOTFOUND)



我的docker-compose.yml看起来像这样:

version: '3'
services:
api:
build:
context: .
dockerfile: Dockerfile
image: api
container_name: app-api
restart: unless-stopped
env_file: ./.env
ports:
- '8080:8080'
volumes:
- ./src
- ./node_modules
command: yarn start
depends_on:
- mysql
mysql:
container_name: app-mysql
restart: always
image: mysql:8.0.21
environment:
MYSQL_ROOT_PASSWORD: 'root'
MYSQL_USER: 'app'
MYSQL_PASS: 'password'
MYSQL_DATABASE: 'appdb'
volumes:
- ./data:/var/lib/mysql
ports:
- '3307:3306'

我的.env看起来像这样:

DB_HOST="mysql" // Tried 127.0.0.1, 0.0.0.0
DB_PORT="3306"
DB_USER="app"
DB_PASSWORD="password"
DB_NAME="appdb"
NODE_ENV="DEV"

我从服务中得到的错误:{"message":"Database connection failed with error Error: getaddrinfo ENOTFOUND "mysql"","level":"info","timestamp":"2020-07-27T03:57:55.524Z"}

我可以从MySQL工作台连接到root,我不能连接到用户app。如果api是在不在docker容器中启动的,那么它可以连接到本地db。

似乎根本无法解决主机问题,这是DNS问题吗?我不记得当mysql没有被码头化时,我是否也遇到过同样的问题,但它无法连接到容器外部的数据库。我做错了什么。

编辑:注释掉整个mysql服务完全没有影响,错误消息是一样的。

我构建了一个更简单的API服务来测试设置——它工作正常。一定是我使用的样板API的东西。

如果有人在看,我发现的东西:

  • 最好有一个用户定义的网络,然后将该网络添加到两个服务中
  • 如果api要连接到localhost(机器(MySQL,则将主机设置为host.docker.internal而不是127.0.0.1mysql是有效的——连接到机器上的数据库服务器
  • ./data文件夹实际上并不是空的,mysql似乎把所有的东西都倒在了那里
Docker对.env文件中双引号的解释与unix系统不同。特别是双引号被认为是字符串的一部分。

https://docs.docker.com/compose/env-file/

引号没有特殊处理。这意味着它们是VAL的一部分。

删除.env文件中的引号,一切都会好起来的。

也有同样的问题。我通过Docker compose使用Docker Secrets将mysql主机加载到我的Node应用程序中,并在我的秘密文件末尾添加了一行mysql主机名。

sooo,如果你正在使用Docker Secrets,你可能想检查你的秘密文件末尾是否有一个不需要的换行符。

最终解决了同样的问题。导致

docker create network xxx

仅网络层

docker run -d --network xxx --network-alias xxx-host
-v todo-mysql-data:/var/lib/mysql 
-e MYSQL_ROOT_PASSWORD=secret 
-e MYSQL_DATABASE=todos 
mysql:5.7

文件中不明显。网络只是一层。网络别名是主机。所以我们通过网络主机启动我们的应用程序。我们需要通过主机使用网络别名。

https://docs.docker.com/get-started/07_multi_container/

最新更新