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

Docker Compose下Node.js与MySQL服务连接失败问题求助

Node.js服务无法连接Docker Compose部署的MySQL服务

我通过Docker Compose部署了2个Node.js服务和2个MySQL服务,能使用对应凭证登录两个MySQL容器,但两个Node.js服务均无法连接MySQL服务,报错信息为:
original: Error: connect ECONNREFUSED 172.22.0.2:3308
此外,我已成功通过PHP脚本连接两个MySQL服务。以下是我的docker-compose.yml文件:

version: '3.8'
services:
  genreapp:
    depends_on:
      - genresqldb
    build: ./genre
    #command: sh -c './wait-for-it.sh -t 0 genresqldb:$DB_PORT_GENRE'
    restart: unless-stopped
    env_file: ./.env
    links:
      - genresqldb
    volumes:
      - ./:/app
    ports:
      - $NODE_PORT_GENRE:$NODE_PORT_GENRE
    environment:
      - DB_USERNAME=$DB_USERNAME
      - DB_PASSWORD=$DB_PASSWORD_GENRE
      - DB_NAME=$DB_NAME_GENRE
      - DB_PORT=$DB_PORT_GENRE
      - DIALTEC=$DIALTEC
      - APP_PORT=$NODE_PORT_GENRE
      - HOST=$HOST
      - DB_HOST_GENRE=genresqldb
    stdin_open: true
    tty: true
  movieapp:
    depends_on:
      - moviesqldb
    build: ./movie
    restart: unless-stopped
    env_file: ./.env
    links:
      - moviesqldb
    volumes:
    - ./:/app
    #command: sh -c './wait-for-it.sh -t 0 moviesqldb:$DB_PORT_MOVIE'
    ports:
      - $NODE_PORT_MOVIE:$NODE_PORT_MOVIE
    environment:
      - DB_USERNAME=$DB_USERNAME
      - DB_PASSWORD=$DB_PASSWORD_MOVIE
      - DB_NAME=$DB_NAME_MOVIE
      - DB_PORT=$DB_PORT_MOVIE
      - DIALTEC=$DIALTEC
      - APP_PORT=$NODE_PORT_MOVIE
      - HOST=$HOST
      - DB_HOST_GENRE=moviesqldb
    stdin_open: true
    tty: true
  genresqldb:
    image: mysql:5
    # restart: unless-stopped
    env_file: ./.env
    environment:
      - MYSQL_ROOT_PASSWORD=$DB_PASSWORD_GENRE
      - MYSQL_DATABASE=$DB_NAME_GENRE
    expose:
      - $DB_PORT_GENRE
    ports:
      - $DB_PORT_GENRE:$DB_PORT
    volumes:
      - db:/var/lib/mysqli
  moviesqldb:
    image: mysql:5
    # restart: unless-stopped
    env_file: ./.env
    environment:
      - MYSQL_ROOT_PASSWORD=$DB_PASSWORD_MOVIE
      - MYSQL_DATABASE=$DB_NAME_MOVIE
    expose:
      - $DB_PORT_MOVIE
    ports:
      - $DB_PORT_MOVIE:$DB_PORT
    volumes:
      - db:/var/lib/mysqli
volumes:
  db:

问题排查与解决方案

1. 端口配置错误

MySQL容器内部默认监听端口是3306,你的配置中ports字段写的是$DB_PORT_GENRE:$DB_PORT,如果.env里的DB_PORT不是3306,会导致容器内部端口映射错误。Node.js服务连接MySQL时,应该用容器内部的3306端口,而非宿主机的映射端口(比如报错里的3308)。

2. 环境变量命名错误

movieapp服务的环境变量里错写了DB_HOST_GENRE=moviesqldb,应该改成对应服务的主机变量(比如DB_HOST_MOVIE=moviesqldb),否则Node.js代码会读取错误的主机地址。

3. 数据库未就绪就启动Node.js服务

depends_on仅保证容器启动顺序,不确保MySQL服务已经完全就绪可以接收连接。你注释掉了wait-for-it.sh脚本,导致Node.js可能在MySQL初始化完成前就尝试连接,引发连接拒绝错误。

4. 数据卷冲突

两个MySQL服务共用同一个db数据卷,会导致数据库文件互相覆盖,损坏数据结构,进而无法正常连接。需要给每个MySQL服务分配独立的数据卷。

5. 冗余配置干扰

links和expose在Docker Compose默认网络下是冗余配置,而且expose里写的是宿主机端口(比如$DB_PORT_GENRE),不是容器内部的3306,反而可能造成混淆。


修正后的docker-compose.yml示例

version: '3.8'
services:
  genreapp:
    depends_on:
      - genresqldb
    build: ./genre
    # 等待MySQL服务就绪后启动
    command: sh -c './wait-for-it.sh -t 0 genresqldb:3306'
    restart: unless-stopped
    env_file: ./.env
    volumes:
      - ./:/app
    ports:
      - $NODE_PORT_GENRE:$NODE_PORT_GENRE
    environment:
      - DB_USERNAME=$DB_USERNAME
      - DB_PASSWORD=$DB_PASSWORD_GENRE
      - DB_NAME=$DB_NAME_GENRE
      - DB_PORT=3306  # 容器内部固定端口
      - DIALTEC=$DIALTEC
      - APP_PORT=$NODE_PORT_GENRE
      - HOST=$HOST
      - DB_HOST=genresqldb  # 用服务名作为主机地址
    stdin_open: true
    tty: true
  movieapp:
    depends_on:
      - moviesqldb
    build: ./movie
    command: sh -c './wait-for-it.sh -t 0 moviesqldb:3306'
    restart: unless-stopped
    env_file: ./.env
    volumes:
      - ./:/app
    ports:
      - $NODE_PORT_MOVIE:$NODE_PORT_MOVIE
    environment:
      - DB_USERNAME=$DB_USERNAME
      - DB_PASSWORD=$DB_PASSWORD_MOVIE
      - DB_NAME=$DB_NAME_MOVIE
      - DB_PORT=3306
      - DIALTEC=$DIALTEC
      - APP_PORT=$NODE_PORT_MOVIE
      - HOST=$HOST
      - DB_HOST=moviesqldb  # 修正环境变量名
    stdin_open: true
    tty: true
  genresqldb:
    image: mysql:5
    restart: unless-stopped
    env_file: ./.env
    environment:
      - MYSQL_ROOT_PASSWORD=$DB_PASSWORD_GENRE
      - MYSQL_DATABASE=$DB_NAME_GENRE
    ports:
      - $DB_PORT_GENRE:3306  # 宿主机端口映射到容器内部3306
    volumes:
      - genredb:/var/lib/mysql  # 独立数据卷
  moviesqldb:
    image: mysql:5
    restart: unless-stopped
    env_file: ./.env
    environment:
      - MYSQL_ROOT_PASSWORD=$DB_PASSWORD_MOVIE
      - MYSQL_DATABASE=$DB_NAME_MOVIE
    ports:
      - $DB_PORT_MOVIE:3306
    volumes:
      - moviedb:/var/lib/mysql  # 独立数据卷
volumes:
  genredb:
  moviedb:

内容的提问来源于stack exchange,提问作者Ndeem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 11:11:16