Docker Compose 和 Dockerfile 有什么区别?
Dockerfile 定义单个镜像怎么构建(装什么、拷什么、怎么启动);docker-compose.yml 定义多个容器怎么协同运行(用哪些镜像、网络、卷、端口)。一个管"造",一个管"跑"。本文讲清分工与配合。
一句话区别:Dockerfile 管"造镜像"——单个应用的打包配方(基础镜像、装依赖、拷代码、启动命令);docker-compose.yml 管"跑应用"——多个容器怎么组合运行(用哪些镜像、端口映射、卷、环境变量、启动顺序)。两者是构建期与运行期的分工,通常配合出现。
Dockerfile:镜像的配方
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["gunicorn", "-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 # 直接用现成镜像
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
回答的问题:整套应用由哪几个服务组成、互相怎么连、数据放哪、对外开什么口。产物是一组跑起来的容器。
分工对照
| Dockerfile | docker-compose.yml | |
|---|---|---|
| 阶段 | 构建期 | 运行期 |
| 作用对象 | 单个镜像 | 多容器应用 |
| 典型内容 | FROM/RUN/COPY/CMD | image/build/ports/volumes/depends_on |
| 命令 | docker build | docker compose up |
配合方式
compose 的 build: . 引用 Dockerfile 现场构建;image: 直接用现成镜像。一个项目里:自研服务走 build,基础设施(DB、Redis)走 image。
可以只用 Dockerfile 吗? 可以——单容器应用 build + run 就够。
可以只用 compose 吗? 可以——全部用现成镜像时不需要 Dockerfile。
观测云对照
从构建到运行全链可观测。 Dockerfile 构建产出的镜像版本、compose 编排起来的容器状态与日志,在观测云里按服务聚合,构建-部署-运行三个阶段的数据连成一条线。
常见问题(FAQ)
Q:docker-compose 里的 command 和 Dockerfile 的 CMD 冲突吗?
A:command 会覆盖 CMD——运行期配置优先于构建期默认。
Q:能把 environment 写进 Dockerfile 吗?
A:ENV 指令可以,但那会固化进镜像;环境相关配置(密码、地址)应该放 compose/运行时注入,镜像保持环境无关。
Q:compose 能管构建吗?
A:docker compose build 就是调 build 配置逐个构建;但复杂构建流水线还是直接 docker build 或 CI 工具更灵活。