docker-compose up 是你学的第一个命令。而之后的部分——网络、密钥、健康检查、不同环境的 profiles——才是区分功能性配置和可用于生产环境的列表的关键。
目录
干净的基础结构
name: mi-app
services:
api:
build:
context: .
dockerfile: Dockerfile
target: production # multi-stage target
environment:
NODE_ENV: production
env_file: .env.production # never hardcode credentials
ports:
- "3000:3000"
depends_on:
db:
condition: service_healthy # wait for DB to be ready
restart: unless-stopped
db:
image: postgres:17-alpine
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
volumes:
postgres_data:
secrets:
db_password:
file: ./secrets/db_password.txtcompose.yml
Multi-stage builds:更小体积,更多安全
生产环境的 Dockerfile 永远不应该包含开发工具:
# Stage 1: dependencies and build
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci # [!code highlight]
COPY . .
RUN npm run build
# Stage 2: minimal final image
FROM node:22-alpine AS production # [!code ++]
WORKDIR /app # [!code ++]
# Only copy what's necessary
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node # don't run as root
EXPOSE 3000
CMD ["node", "dist/server.js"]Dockerfile
体积差异可能是 600 MB → 80 MB。
不同环境的 profiles
使用 profiles 你可以根据上下文激活服务,而无需维护多个 Compose 文件:
services:
api:
# no profile = always active
build: .
adminer:
image: adminer
profiles: [dev, debug] # only in dev
ports:
- "8080:8080"
prometheus:
image: prom/prometheus
profiles: [monitoring] # only when you need it
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.ymlcompose.yml
# Only bring up API + DB
docker compose up
# Bring up with dev tools
docker compose --profile dev up
# Full monitoring stack
docker compose --profile monitoring up
真正有效的 Healthchecks
基本的 depends_on 只等待容器启动,而不是等待服务就绪。这个区别很重要:
services:
redis:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 10
start_period: 10s # initial grace time
worker:
build: .
depends_on:
redis:
condition: service_healthy # wait for green healthcheckcompose.yml
Networking:默认隔离
每个 compose.yml 创建自己的网络。要连接独立的 stacks:
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # no internet access
services:
nginx:
networks: [frontend, backend] # only one touching both networks
api:
networks: [backend] # isolated from outside
db:
networks: [backend] # samecompose.yml
生产前检查清单
- 敏感变量放在
secrets或.env中,不在仓库内 - Multi-stage build 已启用
- 所有关键服务都配置了
restart: unless-stopped - Healthchecks 配置了适当的
start_period -
depends_on使用condition: service_healthy - 容器使用非 root 用户(
USER node、USER app) - 使用命名卷持久化数据(生产环境不用 bind mounts)
- 根据容器内存配置
--max-old-space-size
教程级别的
compose.yml和生产级别的compose.yml的区别不在于行数——而在于知道什么会出错并已经将其纳入考量。