Docker Compose
用一个 compose.yaml 描述多容器应用,一条命令起停整套环境。
Key PointsCompose 是单机多容器编排:一份 YAML 定义服务、网络、卷,up 一起起、down 一起清。
一份 compose.yaml
YAML
services:
api:
build: .
ports:
- "8080:8080"
environment:
DB_HOST: db
DB_USER: app
DB_PASSWORD: secret
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: app
MYSQL_USER: app
MYSQL_PASSWORD: secret
volumes:
- db-data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-uroot", "-proot"]
interval: 5s
timeout: 3s
retries: 20
volumes:
db-data:常用命令
Bash
docker compose up -d # 后台起全部服务
docker compose ps
docker compose logs -f api
docker compose exec api sh
docker compose restart api
docker compose down # 停并删容器、网络
docker compose down -v # 连卷一起删(数据没了)关键字段
| Field | Meaning |
|---|---|
build | Build from a Dockerfile in this dir |
image | Use an existing image |
depends_on | Start order; with condition waits for health |
volumes | Named volume or bind mount |
environment / env_file | Env vars inline or from a file |
restart | no / always / on-failure / unless-stopped |
profiles | Only start with --profile x |
开发时的热更新
YAML
services:
api:
build:
context: .
target: dev
volumes:
- .:/app # 源码挂进容器
- /app/node_modules # 用镜像里的依赖,避免覆盖
command: npm run devThe second line is an anonymous volume: it masks the container's node_modules so a host directory cannot overwrite Linux-built native modules.
depends_on only orders startup, it does not wait for readiness. Without healthcheck + condition: service_healthy (or retries in the app), the API will still hit a database that is not ready.多环境
Bash
# compose.override.yaml 会自动叠加(开发用)
docker compose up -d
# 指定多个文件,后面的覆盖前面的
docker compose -f compose.yaml -f compose.prod.yaml up -d
# 用 --env-file 换一套变量
docker compose --env-file .env.prod up -d一份 compose.yaml
YAML
services:
api:
build: .
ports:
- "8080:8080"
environment:
DB_HOST: db
DB_USER: app
DB_PASSWORD: secret
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: app
MYSQL_USER: app
MYSQL_PASSWORD: secret
volumes:
- db-data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-uroot", "-proot"]
interval: 5s
timeout: 3s
retries: 20
volumes:
db-data:常用命令
Bash
docker compose up -d # 后台起全部服务
docker compose ps
docker compose logs -f api
docker compose exec api sh
docker compose restart api
docker compose down # 停并删容器、网络
docker compose down -v # 连卷一起删(数据没了)关键字段
| 字段 | 含义 |
|---|---|
build | 用当前目录的 Dockerfile 构建 |
image | 使用现成镜像 |
depends_on | 启动顺序;配 condition 可等健康检查 |
volumes | 命名卷或目录挂载 |
environment / env_file | 直接写或从文件读 |
restart | 重启策略 |
profiles | 仅在某 profile 下启动 |
开发时的热更新
YAML
services:
api:
build:
context: .
target: dev
volumes:
- .:/app # 源码挂进容器
- /app/node_modules # 用镜像里的依赖,避免覆盖
command: npm run dev第二行 - /app/node_modules 是匿名卷:它把容器里的 node_modules 遮住,防止宿主目录(可能是 macOS/Windows 的)把 Linux 编译的原生模块覆盖掉。
depends_on 默认只保证启动顺序,不保证依赖已经就绪。数据库还没初始化完,应用照样连不上。要么配 healthcheck + condition: service_healthy,要么在应用里做重试。多环境
Bash
# compose.override.yaml 会自动叠加(开发用)
docker compose up -d
# 指定多个文件,后面的覆盖前面的
docker compose -f compose.yaml -f compose.prod.yaml up -d
# 用 --env-file 换一套变量
docker compose --env-file .env.prod up -d