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

Docker Compose集成MySQL启动失败,应用无法连接数据库求助

Docker Compose 连接 MySQL 超时问题排查

问题描述

我正在跟随Docker教程搭建一个包含MySQL数据库的简单Hello World级Docker Compose项目,但启动失败。以下是我的docker-compose.yml配置:

services:
  app:
    image: node:18-alpine
    command: sh -c "yarn install && yarn run dev"
    ports:
      - 3000:3000
    working_dir: /app
    volumes:
      - ./:/app
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: secret
      MYSQL_DB: todos

  mysql:
    image: mysql:8.0
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: todos

volumes:
  todo-mysql-data:

单独启动各服务时应用可正常运行,但执行docker compose up时,MySQL容器看似已就绪,但应用服务无法连接到数据库,日志信息如下:

> sudo docker compose logs -f
...
app-mysql-1  | 2023-05-24T09:05:29.562329Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.33'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL.
app-app-1    | Waiting for mysql:3306.......
app-app-1    | Timeout

我可以通过sudo docker exec -it <mysql-container-id> mysql -u root -p正常连接到数据库,尝试为应用服务添加延迟等待数据库启动后问题仍未解决,请问有什么解决思路?

解决思路

  • 替换简单延迟为数据库就绪检测:简单sleep延迟不可靠,MySQL日志显示"ready for connections"后,可能还需要几秒完成权限初始化、数据库创建等操作。可以在app服务的启动命令中加入基于mysql-client的检测逻辑:

    command: sh -c "apk add --no-cache mysql-client && while ! mysql -h mysql -u root -psecret -e 'SELECT 1'; do sleep 1; done && yarn install && yarn run dev"
    

    该命令会循环检测,直到成功执行SQL查询后再启动应用。

  • 排查MySQL 8.0认证插件兼容性:MySQL 8.0默认使用caching_sha2_password认证插件,部分旧版本Node.js MySQL客户端(如mysql包)不支持该插件。可修改MySQL服务配置,强制使用mysql_native_password:

    mysql:
      image: mysql:8.0
      command: --default-authentication-plugin=mysql_native_password
      volumes:
        - todo-mysql-data:/var/lib/mysql
      environment:
        MYSQL_ROOT_PASSWORD: secret
        MYSQL_DATABASE: todos
    

    同时确保Node.js项目的数据库客户端版本适配,或切换为支持caching_sha2_password的客户端(如mysql2)。

  • 验证容器网络与数据库连通性:进入app容器内部,手动测试网络连通和数据库访问:

    sudo docker exec -it app-app-1 sh
    # 测试DNS解析与网络连通
    ping mysql
    # 尝试连接数据库
    mysql -h mysql -u root -psecret todos
    

    若ping不通,检查Docker Compose默认网络状态;若ping通但连接失败,重点排查认证插件或权限配置。

  • 配置MySQL健康检查与服务依赖:通过健康检查让Docker Compose等待MySQL真正就绪后再启动app服务:
    首先为mysql服务添加健康检查:

    mysql:
      image: mysql:8.0
      volumes:
        - todo-mysql-data:/var/lib/mysql
      environment:
        MYSQL_ROOT_PASSWORD: secret
        MYSQL_DATABASE: todos
      healthcheck:
        test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-psecret"]
        interval: 2s
        timeout: 20s
        retries: 10
    

    然后在app服务中配置依赖mysql的健康状态:

    app:
      image: node:18-alpine
      command: sh -c "yarn install && yarn run dev"
      ports:
        - 3000:3000
      working_dir: /app
      volumes:
        - ./:/app
      environment:
        MYSQL_HOST: mysql
        MYSQL_USER: root
        MYSQL_PASSWORD: secret
        MYSQL_DB: todos
      depends_on:
        mysql:
          condition: service_healthy
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 18:05:39