10.3.1 编排文件怎么写——Compose 文件结构:服务定义与依赖关系
一个 YAML 文件,定义整个应用栈。
文件结构概览
yaml
# docker-compose.yml 基本结构
services: # 服务定义(必需)
web:
...
api:
...
volumes: # 数据卷定义(可选)
db-data:
networks: # 网络定义(可选)
app-network:完整示例:全栈应用
yaml
services:
# Next.js 前端
frontend:
build: ./frontend
ports:
- "3000:3000"
environment:
- NEXT_PUBLIC_API_URL=http://api:3001
depends_on:
- api
# NestJS 后端
api:
build: ./api
ports:
- "3001:3001"
environment:
- DATABASE_URL=postgresql://postgres:password@postgres:5432/mydb
- REDIS_URL=redis://redis:6379
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
# PostgreSQL 数据库
postgres:
image: postgres:15
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
- POSTGRES_DB=mydb
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
# Redis 缓存
redis:
image: redis:7-alpine
volumes:
- redis-data:/data
volumes:
postgres-data:
redis-data:服务配置详解
镜像来源
yaml
services:
# 方式一:使用现有镜像
postgres:
image: postgres:15
# 方式二:从 Dockerfile 构建
api:
build: ./api
# 或详细配置
build:
context: ./api
dockerfile: Dockerfile.prod
args:
- NODE_ENV=production端口映射
yaml
services:
api:
ports:
- "3001:3001" # 宿主机:容器
- "127.0.0.1:3001:3001" # 仅本机访问
expose:
- "3001" # 仅容器间访问,不对外环境变量
yaml
services:
api:
# 方式一:直接定义
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://...
# 方式二:从文件加载
env_file:
- .env
- .env.production数据卷
yaml
services:
postgres:
volumes:
# 命名卷(推荐,Docker 管理)
- postgres-data:/var/lib/postgresql/data
# 绑定挂载(直接映射主机目录)
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
volumes:
postgres-data: # 声明命名卷依赖关系配置
基本依赖
yaml
services:
api:
depends_on:
- postgres
- redis问题:depends_on 只保证启动顺序,不保证服务就绪。
带健康检查的依赖
yaml
services:
api:
depends_on:
postgres:
condition: service_healthy # 等待健康检查通过
redis:
condition: service_started # 只等待启动重启策略
yaml
services:
api:
restart: always # 总是重启
# 可选值
# no - 不重启(默认)
# always - 总是重启
# on-failure - 仅失败时重启
# unless-stopped - 除非手动停止资源限制
yaml
services:
api:
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M文件组织最佳实践
project/
├── docker-compose.yml # 基础配置
├── docker-compose.override.yml # 开发环境覆盖(自动加载)
├── docker-compose.prod.yml # 生产环境配置
├── .env # 环境变量
├── frontend/
│ └── Dockerfile
└── api/
└── Dockerfile常见错误
| 错误 | 原因 | 解决方案 |
|---|---|---|
service "api" depends on undefined service | 依赖的服务名拼写错误 | 检查服务名 |
port is already allocated | 端口被占用 | 修改端口或停止占用进程 |
volume "xxx" not found | 卷未声明 | 在 volumes 顶级键中声明 |
AI 协作指南
向 AI 描述需求时:
请帮我生成一个 docker-compose.yml,包含:
- Next.js 前端(端口 3000)
- NestJS 后端(端口 3001)
- PostgreSQL 数据库
- Redis 缓存
要求:后端等待数据库健康后再启动,数据需要持久化关键术语:services、depends_on、healthcheck、volumes、networks
