Docker Compose在MySQL和NodeJS中获取错误ECONNREFUSED 127.0.0.1:3306



我正试图在Windows 10主机中使用Docker Compose为我的NestJS+TypeORM+MySQL环境设置一些容器,但我收到了一个ECONNREFUSED错误:

connect ECONNREFUSED 127.0.0.1:3306 +2ms
backend_1  | Error: connect ECONNREFUSED 127.0.0.1:3306
backend_1  |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1145:16)
backend_1  |     --------------------
backend_1  |     at Protocol._enqueue (/usr/src/app/node_modules/mysql/lib/protocol/Protocol.js:144:48)
backend_1  |     at Protocol.handshake (/usr/src/app/node_modules/mysql/lib/protocol/Protocol.js:51:23)        
backend_1  |     at PoolConnection.connect (/usr/src/app/node_modules/mysql/lib/Connection.js:116:18)
backend_1  |     at Pool.getConnection (/usr/src/app/node_modules/mysql/lib/Pool.js:48:16)
backend_1  |     at /usr/src/app/node_modules/typeorm/driver/mysql/MysqlDriver.js:793:18
backend_1  |     at new Promise (<anonymous>)
backend_1  |     at MysqlDriver.createPool (/usr/src/app/node_modules/typeorm/driver/mysql/MysqlDriver.js:790:16)
backend_1  |     at MysqlDriver.<anonymous> (/usr/src/app/node_modules/typeorm/driver/mysql/MysqlDriver.js:278:51)
backend_1  |     at step (/usr/src/app/node_modules/typeorm/node_modules/tslib/tslib.js:141:27)
backend_1  |     at Object.next (/usr/src/app/node_modules/typeorm/node_modules/tslib/tslib.js:122:57)

我已经创建了以下Dockerfile来配置NestJS API容器:

FROM node:12-alpine
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
EXPOSE 3000
#CMD ["npm", "start"]
CMD /wait-for-it.sh db:3306 -- npm start
COPY . .

然后我引用了Docker Compose中的以下docker-compose.yml:

version: "3.8"
networks:
app-tier:
driver: bridge
services:
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
expose:
- "3306"
ports:
- "3306:3306"    
networks:
- app-tier      
environment:
MYSQL_DATABASE: school
MYSQL_ALLOW_EMPTY_PASSWORD: ok
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: dbuser
MYSQL_PASSWORD: dbuser
MYSQL_ROOT_HOST: '%'
backend:
depends_on:
- db
build: .
ports:
- "3000:3000"
networks:
- app-tier      

最后,我将TypeORM配置设置为与Docker Compose文件匹配:

export const DB_CONFIG: TypeOrmModuleOptions = {
type: 'mysql',
host: 'db',
port: 3306,
username: 'dbuser',
password: 'dbuser',
database: 'school',
entities: [], // We specify the entities in the App Module.
synchronize: true,
};

我是Docker Compose的新手,但我尝试过很多事情,比如将输出端口更改为3307,设置显式网络。。。当我运行主机操作系统时,3306端口是空闲的。有什么帮助吗?

编辑1

我已经按照建议包括了MYSQL_ROOT_HOSTwait-for-it.sh,但仍然没有结果。

我认为你的数据库需要更多的时间来启动,并且你的应用程序在数据库之前启动,请对你的docker-compose.yml文件尝试这样的操作:

version: "3.8"
networks:
app-tier:
driver: bridge
services:
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
expose:
- "3306"
ports:
- "3306:3306"    
networks:
- app-tier      
environment:
MYSQL_DATABASE: school
MYSQL_ALLOW_EMPTY_PASSWORD: ok
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: dbuser
MYSQL_PASSWORD: dbuser
MYSQL_ROOT_HOST: '%'
backend:
depends_on:
- db
build: .
command: bash -c 'while !</dev/tcp/db/3306; do sleep 1; done; npm start'
ports:
- "3000:3000"
networks:
- app-tier   

您可以利用健康检查来正常检查服务是否处于健康状态,如果在最大尝试次数后未达到该状态,则正常失败。

数据库服务的运行状况检查可能类似于

healthcheck:
test: mysqladmin ping -h mysql --user=$$MYSQL_USER --password=$$MYSQL_ROOT_PASSWORD
interval: 30s
timeout: 12s
retries: 10

然后在后端添加一个依赖的

depends_on:
db:
condition: service_healthy

这将在数据库正常后启动后端,并在尝试10次后失败,每次尝试之间等待30秒。这对前面的答案是有利的,因为如果mysql永远不会出现,它就不会永远挂起

最新更新