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

如何从Docker镜像连接到docker-compose创建的数据库容器?

解决Docker容器无法连接docker-compose启动的数据库问题

问题根源

docker-compose默认会为当前项目创建一个专属Docker网络,而通过docker run单独启动的容器默认使用Docker的bridge默认网络。两个不同网络的容器之间无法直接通过服务名(如database)通信,且容器内的localhost指向容器自身而非宿主机,因此会出现连接失败的错误。

解决方案一:将app容器加入docker-compose的专属网络

  1. 查看docker-compose创建的网络名称
    执行以下命令列出所有Docker网络:

    docker network ls
    

    找到对应项目的网络,名称通常为[项目目录名]_default(比如你的项目目录叫myapp,网络名就是myapp_default)。

  2. 修改app容器启动命令
    启动app容器时,通过--network参数加入上述专属网络,同时修改DATABASE_URL的主机为docker-compose中数据库服务的名称database,端口使用容器内部的3306(同一网络内直接访问服务内部端口,无需用宿主机映射的3309):

    docker run -p 3000:3000 --network myapp_default -e DATABASE_URL=mysql://root:foobar@database:3306/app app_image
    

解决方案二:将app服务加入docker-compose.yml(更推荐)

把app服务整合到docker-compose配置中,所有服务默认在同一网络,无需手动处理网络配置,还能通过配置控制启动顺序:

修改后的docker-compose.yml:

version: '3'

services:
  database:
    image: mysql:8.0
    environment:
      - MYSQL_DATABASE=app
      - MYSQL_ROOT_PASSWORD=foobar
    volumes:
      - db:/var/lib/mysql
    # 添加健康检查,确保数据库启动完成后再启动app
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-pfoobar"]
      interval: 10s
      timeout: 5s
      retries: 5

  app:
    image: app_image
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=mysql://root:foobar@database:3306/app
    depends_on:
      database:
        condition: service_healthy # 等待数据库健康检查通过再启动
    restart: unless-stopped # 数据库重启后自动重启app

volumes:
    db:

启动命令:

docker-compose up -d

额外注意事项

  • 数据库启动需要时间,如果app启动时数据库还未初始化完成,迁移可能失败。上述配置中的healthcheck和depends_on的service_healthy条件可以解决这个问题。
  • 同一网络内不要使用宿主机的端口(如3309)访问数据库,直接用服务内部端口3306即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 15:05:25