You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Docker-Compose时Sequelize迁移出现ECONNREFUSED错误

问题原因分析

你碰到的这个问题是Docker Compose里depends_on的典型坑——它只保证容器的启动顺序,但不会等MySQL服务完全初始化就绪。当你的应用容器开始执行sequelize db:migrate时,数据库容器虽然已经启动,但MySQL可能还在加载系统表、初始化权限,压根没准备好接收连接,所以才会抛出ECONNREFUSED错误。

另外还有个小细节:你的database.js里用到了DB_PASSWORD和DB_NAME环境变量,但docker-compose的app服务配置里没传这俩参数,默认值虽然能凑合用,但最好统一配置避免后续出问题。

解决方案1:用等待脚本做前置检查(推荐)

可以在应用启动前先检测MySQL服务是否可用,常用的工具是wait-for-it.sh脚本,步骤如下:

  1. 下载脚本到项目根目录:
    curl -O https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh
    chmod +x wait-for-it.sh
    
  2. 修改docker-compose.yml的app服务命令,让它先等MySQL就绪再启动:
    app:
      build: .
      ports:
        - '3333:3333'
      command: ["./wait-for-it.sh", "database:3306", "--", "yarn", "start"]
      environment:
        - DB_HOST=database
        - DB_USER=root
        - DB_PASSWORD=123123  # 补上缺失的环境变量
        - DB_NAME=test
      depends_on:
        - database
    

解决方案2:在代码里加连接重试逻辑

自己写个简单的Node.js脚本,循环尝试连接数据库,成功后再执行迁移:

  1. 新建wait-for-db.js文件:
    const { Sequelize } = require('sequelize');
    const config = require('./src/config/database');
    
    const sequelize = new Sequelize(config.database, config.username, config.password, {
      host: config.host,
      dialect: 'mysql'
    });
    
    async function checkDBConnection() {
      try {
        await sequelize.authenticate();
        console.log('数据库连接成功,开始执行迁移...');
        process.exit(0);
      } catch (err) {
        console.log('数据库还没就绪,2秒后重试...');
        setTimeout(checkDBConnection, 2000);
      }
    }
    
    checkDBConnection();
    
  2. 修改package.json的启动脚本:
    "scripts": {
      "wait-for-db": "node wait-for-db.js",
      "start": "yarn wait-for-db && npx sequelize db:migrate && npx sequelize db:seed:all && node src/app/index.js"
    },
    

解决方案3:用Docker Compose健康检查(需Compose 3.4+)

给数据库服务添加健康检查,让应用容器只在数据库真正就绪后启动:

version: '3.8'
services:
  database:
    image: mysql:5.7
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=123123
      - MYSQL_DATABASE=test
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p123123"]
      interval: 5s
      timeout: 5s
      retries: 5
  app:
    build: .
    ports:
      - '3333:3333'
    command: yarn start
    environment:
      - DB_HOST=database
      - DB_USER=root
      - DB_PASSWORD=123123
      - DB_NAME=test
    depends_on:
      database:
        condition: service_healthy

内容的提问来源于stack exchange,提问作者Matheus Campos da Silva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:10:25