Docker Compose
Docker Compose 的核心概念:services、networks、volumes、depends_on、environment、profiles。
#type / howto
#status / growing
#tech / ops
#resource / docker
[!info] related notes
- 所属 MOC: Docker MOC, Build Tools MOC
- 前置概念: Docker
- 相关应用: docker创建开发测试数据库
Docker Compose
一句话定义
Docker Compose 用一个 YAML 文件定义和管理多容器应用,一条命令启动整个服务栈。
基本结构
# docker-compose.yml
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgres://user:pass@db:5432/mydb
depends_on:
- db
- redis
db:
image: postgres:16
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: mydb
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:
services
每个 service 是一个容器的配置:
services:
app:
# 从 Dockerfile 构建
build:
context: .
dockerfile: Dockerfile
args:
- NODE_ENV=production
# 或直接使用镜像
image: node:20-alpine
# 端口映射(宿主机:容器)
ports:
- "8080:3000"
- "9229:9229" # 调试端口
# 环境变量
environment:
- NODE_ENV=production
# 或从文件读取
env_file:
- .env
- .env.production
# 命令覆盖
command: ["node", "server.js"]
# 工作目录
working_dir: /app
# 重启策略
restart: unless-stopped
# 资源限制
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
networks
services:
web:
networks:
- frontend
- backend
db:
networks:
- backend
networks:
frontend:
backend:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/16
- 默认所有 service 在同一个网络,可以用服务名互相访问
- 自定义网络可以隔离服务间的通信
volumes
services:
db:
volumes:
# 命名卷(持久化,Docker 管理)
- postgres_data:/var/lib/postgresql/data
# 绑定挂载(宿主机目录)
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
# 只读挂载
- ./config:/etc/app/config:ro
volumes:
postgres_data: # 声明命名卷
- 命名卷:Docker 管理生命周期,适合数据库数据
- 绑定挂载:直接映射宿主机目录,适合开发时热重载
depends_on
services:
web:
depends_on:
db:
condition: service_healthy # 等 db 健康检查通过
redis:
condition: service_started # 只等 redis 启动
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user"]
interval: 5s
timeout: 5s
retries: 5
service_started:容器启动即可(默认)service_healthy:健康检查通过才算就绪service_completed_successfully:容器退出且退出码为 0
environment 与 env_file
services:
app:
# 直接定义
environment:
NODE_ENV: production
DEBUG: "app:*"
# 或从文件读取
env_file:
- .env
- .env.local # 优先级更高,覆盖 .env 中的同名变量
# 也可以用列表语法
environment:
- NODE_ENV=production
.env 文件格式:
# .env
NODE_ENV=production
DATABASE_URL=postgres://user:pass@db:5432/mydb
REDIS_URL=redis://redis:6379
profiles
按需启动服务,避免启动所有容器:
services:
web:
image: node:20
# 无 profile,默认启动
db:
image: postgres:16
# 无 profile,默认启动
debug-tools:
image: busybox
profiles:
- debug # 只在指定 profile 时启动
monitoring:
image: prometheus
profiles:
- monitoring
# 启动方式:
# docker compose up -> 只启动 web 和 db
# docker compose --profile debug up -> 启动 web、db、debug-tools
# docker compose --profile debug --profile monitoring up -> 全部启动
常用命令
# 启动所有服务(后台)
docker compose up -d
# 查看运行中的服务
docker compose ps
# 查看日志
docker compose logs -f web # 只看 web 的日志
# 停止并删除容器(保留卷)
docker compose down
# 停止并删除容器和卷
docker compose down -v
# 重建镜像并启动
docker compose up -d --build
# 进入容器
docker compose exec web sh
# 运行一次性命令
docker compose run --rm web npm test
常见误区
depends_on不等服务就绪:需要condition: service_healthy+healthcheck- 服务间通信用服务名:不是
localhost,是db、redis等服务名 volumes声明在顶层:服务中引用的是顶层声明的命名卷.env和environment的优先级:environment>.env.local>.envrestart: always不适合开发:开发环境用no或on-failure