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

如何将Web服务与数据库作为单个镜像推送至Docker Registry?

问题:Docker Compose多服务部署后,其他机器无法自动拉取依赖的DB服务

我的环境配置

docker-compose.yml:

version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: docker
      MYSQL_ROOT_PASSWORD: supersecret
      MYSQL_USER: superuser
      MYSQL_PASSWORD: supersecret
      DATABASE_HOST: db
  web:
    build: ./web
    image: jonas/testapp:2
    links:
      - db
    ports:
      - "3333:3333"
    depends_on:
      - db
    restart: on-failure

web/Dockerfile:

FROM node:10.16.0
WORKDIR /usr/src/app
COPY package.json /usr/src/app
RUN npm install
COPY . /usr/src/app
EXPOSE 3333
CMD npm start

问题现象

  • 本地执行docker-compose up一切正常,MySQL镜像自动拉取,Web服务能正常连接DB
  • 执行docker-compose push时,只有jonas/testapp:2被推送到我的镜像仓库
  • 在其他机器执行docker run -it -p 3333:3333 jonas/testapp:2,只能启动Web容器,无法获取DB服务,自然也没法连接

解决方案

首先得明确两个核心逻辑,搞懂了问题就迎刃而解:

  1. docker-compose push只会推送你自定义的、带仓库地址的镜像(也就是你的jonas/testapp:2),官方的mysql:5.7不会被推送(也没必要,Docker Hub本来就有官方镜像)
  2. docker run是单容器运行命令,它完全不知道你本地docker-compose.yml里的DB服务配置,所以只会启动你指定的Web容器,不会自动帮你启动DB

下面是几种可行的解决方案,按推荐程度排序:

1. 在目标机器使用相同的docker-compose.yml(最推荐)

这是Docker Compose多服务部署的标准方式,步骤非常简单:

  • 把你的docker-compose.yml同步到目标机器(可以用Git、scp,或者把文件放到你的镜像仓库对应的代码库)
  • 在目标机器执行:
    docker-compose up -d
    
    Compose会自动处理所有事情:
    • 检查db服务的mysql:5.7镜像,如果本地没有,自动从Docker Hub拉取
    • 检查web服务的jonas/testapp:2镜像,如果本地没有,自动从你的私有仓库拉取(前提是目标机器已经docker login到你的仓库)
    • 自动创建服务间的网络、处理依赖顺序(比如先启动DB再启动Web)、配置环境变量,和你本地运行的效果完全一致

2. 手动拉取镜像并启动(临时应急)

如果只是临时测试,不想同步docker-compose.yml,可以手动操作:

  • 先在目标机器拉取MySQL镜像:
    docker pull mysql:5.7
    
  • 手动创建Docker网络(让Web和DB能互相访问):
    docker network create app-network
    
  • 启动DB容器:
    docker run -d \
      --name db \
      --network app-network \
      -e MYSQL_DATABASE=docker \
      -e MYSQL_ROOT_PASSWORD=supersecret \
      -e MYSQL_USER=superuser \
      -e MYSQL_PASSWORD=supersecret \
      mysql:5.7
    
  • 最后启动Web容器:
    docker run -it \
      --network app-network \
      -e DATABASE_HOST=db \
      -p 3333:3333 \
      jonas/testapp:2
    
    这种方式需要手动配置所有参数,非常繁琐,不适合生产环境。

3. 不要尝试在单个容器里跑多个服务(强烈不推荐)

网上可能会有人建议用supervisord之类的工具在Web容器里同时跑Node和MySQL,但这违反了Docker一个容器一个进程的设计原则,会导致容器体积变大、难以维护、排查问题困难,完全不推荐。


额外注意事项

  • 敏感信息(比如MYSQL_ROOT_PASSWORD)不要硬编码在docker-compose.yml里,建议用.env文件管理,Compose会自动读取该文件的环境变量
  • 如果你的私有仓库需要认证,目标机器必须先执行docker login登录,才能拉取jonas/testapp:2镜像

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:47:31