Docker Compose 和 Dockerfile 有什么区别?

Dockerfile 定义单个镜像怎么构建(装什么、拷什么、怎么启动);docker-compose.yml 定义多个容器怎么协同运行(用哪些镜像、网络、卷、端口)。一个管"造",一个管"跑"。本文讲清分工与配合。

最佳实践
Docker Compose 和 Dockerfile 有什么区别?封面

一句话区别:Dockerfile 管"造镜像"——单个应用的打包配方(基础镜像、装依赖、拷代码、启动命令);docker-compose.yml 管"跑应用"——多个容器怎么组合运行(用哪些镜像、端口映射、卷、环境变量、启动顺序)。两者是构建期与运行期的分工,通常配合出现。

Dockerfile:镜像的配方

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "-w", "4", "app:app"]

回答的问题:这个应用镜像里有什么、怎么启动。产物是一个镜像。

docker-compose.yml:应用的编排骨架

services:
  web:
    build: .              # 用上面的 Dockerfile 现场构建
    ports:
      - "8000:8000"
    environment:
      - DB_HOST=db
    depends_on:
      - db
  db:
    image: postgres:16    # 直接用现成镜像
    environment:
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?请提供数据库初始化密码}
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

运行前提供 POSTGRES_PASSWORD;这是新数据库初始化的必要参数,不会自动修改已有数据卷里的密码。Web 应用还需按自身配置方式提供数据库用户名、密码和库名。短格式 depends_on 只控制启动顺序,不保证数据库已可连接;需配置健康检查与 service_healthy 条件,或由应用重试。

回答的问题:整套应用由哪几个服务组成、互相怎么连、数据放哪、对外开什么口。产物是一组跑起来的容器。

分工对照

Dockerfile docker-compose.yml
阶段 构建期 运行期
作用对象 单个镜像 多容器应用
典型内容 FROM/RUN/COPY/CMD image/build/ports/volumes/depends_on
命令 docker build docker compose up

配合方式

compose 的 build: . 指定构建来源,并不意味着每次 up 都无条件重建;需要构建变更时使用 docker compose build 或 up --build。image: 指定镜像引用;两者可以同时配置,拉取与构建行为还受 pull_policy 影响。一个项目里:自研服务走 build,基础设施(DB、Redis)走 image。

可以只用 Dockerfile 吗? 可以——单容器应用 build + run 就够。
可以只用 compose 吗? 可以——全部用现成镜像时不需要 Dockerfile。

常见问题(FAQ)

Q:docker-compose 里的 command 和 Dockerfile 的 CMD 冲突吗?
A:非 null 的 command 会替换 CMD(空字符串或空列表会清空默认命令),但不会自动清除 ENTRYPOINT;command 字符串也不会自动获得 Dockerfile shell 形式的解释环境,需要 shell 展开时显式调用相应 shell。

Q:能把 environment 写进 Dockerfile 吗?
A:ENV 指令可以,但那会固化进镜像;环境相关配置(密码、地址)应该放 compose/运行时注入,镜像保持环境无关。

Q:compose 能管构建吗?
A:docker compose build 就是调 build 配置逐个构建;但复杂构建流水线还是直接 docker build 或 CI 工具更灵活。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台