这是我的 docker-compose 文件:
version: '3.9'
services:
mysql:
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_DATABASE: 'admindb'
MYSQL_USER: 'admin'
MYSQL_PASSWORD: 'secretpassword'
MYSQL_ROOT_PASSWORD: 'someverysecretpassword'
ports:
- '3306:3306'
- '33060:33060'
volumes:
- ./db:/var/lib/mysql
networks:
- adminnet
app:
image: "node:latest"
depends_on:
- mysql
user: "node"
restart: unless-stopped
working_dir: /home/app
environment:
NODE_ENV: production
volumes:
- ${PWD}/../:/home/app
ports:
- '8081:8081'
command: "npm start"
networks:
- adminnet
volumes:
db:
data:
networks:
adminnet:
这是我的app.js:
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize('admindb', 'admin', 'secretpassword', {
host: 'mysql',
port: 3306,
dialect: 'mysql',
});
sequelize
.authenticate()
.then(() => {
console.log('Connection has been established successfully.');
})
.catch(err => {
console.error('Unable to connect to the database:', err);
});
当我刚刚运行 MySQL 容器时(因此,如果我从 docker-compose 文件中删除“app”实例)并将
host:'mysql'
替换为 host:'127.0.0.1'
并从我的主机运行 npm start
,它能够成功连接到从容器运行的数据库。
但是,如果我从一个容器运行 app.js,该容器应该连接到另一个容器内的数据库,那么它就不起作用。我使用
host:'mysql'
,但我不断收到以下错误:
containers-app-1 | Unable to connect to the database: ConnectionError [SequelizeConnectionError]: connect ETIMEDOUT
containers-app-1 | at ConnectionManager.connect (/home/app/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:102:17)
containers-app-1 | at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
containers-app-1 | at async ConnectionManager._connect (/home/app/node_modules/sequelize/lib/dialects/abstract/connection-manager.js:220:24)
containers-app-1 | at async /home/app/node_modules/sequelize/lib/dialects/abstract/connection-manager.js:174:32
containers-app-1 | at async ConnectionManager.getConnection (/home/app/node_modules/sequelize/lib/dialects/abstract/connection-manager.js:197:7)
containers-app-1 | at async /home/app/node_modules/sequelize/lib/sequelize.js:301:26
containers-app-1 | at async Sequelize.authenticate (/home/app/node_modules/sequelize/lib/sequelize.js:453:5) {
containers-app-1 | parent: Error: connect ETIMEDOUT
containers-app-1 | at Connection._handleTimeoutError (/home/app/node_modules/mysql2/lib/connection.js:189:17)
containers-app-1 | at listOnTimeout (node:internal/timers:564:17)
containers-app-1 | at process.processTimers (node:internal/timers:507:7) {
containers-app-1 | errorno: 'ETIMEDOUT',
containers-app-1 | code: 'ETIMEDOUT',
containers-app-1 | syscall: 'connect',
containers-app-1 | fatal: true
containers-app-1 | },
containers-app-1 | original: Error: connect ETIMEDOUT
containers-app-1 | at Connection._handleTimeoutError (/home/app/node_modules/mysql2/lib/connection.js:189:17)
containers-app-1 | at listOnTimeout (node:internal/timers:564:17)
containers-app-1 | at process.processTimers (node:internal/timers:507:7) {
containers-app-1 | errorno: 'ETIMEDOUT',
containers-app-1 | code: 'ETIMEDOUT',
containers-app-1 | syscall: 'connect',
containers-app-1 | fatal: true
containers-app-1 | }
containers-app-1 | }
某些原因导致节点容器无法连接到 mysql 容器内的数据库。我尝试使用节点容器中的 ping,但该包不可用。
我阅读了大量网页,并在过去的几个小时内进行了调试,但运气不佳。有谁可能知道这个问题吗?我已经尝试过所有类似的 StackOverflow 问题和解决方案,但没有任何运气。
我在我的机器上测试了你的堆栈,第二次运行后我成功运行了。由于您的
depends_on
选项,我运行了两次(请参阅下面的注释)。
这是我的机器规格:
机器: MacBook Air(M1,2020)
操作系统:macOS Monterey v12.4
Docker 版本: 20.10.12(使用其 .dmg 安装)
Docker Compose 版本:未使用——最新版本的 docker 将其作为子命令包含
我认为这个问题有多种原因:
docker-compose.yml
文件的 depends_on
选项。如果您阅读 depends_on
上的 文档,您会发现您的
app
服务不会等待 mysql
健康后再尝试连接。如果您想在连接之前确保 healthcheck
健康,则必须使用
mysql
选项。