用 Docker Compose 编排多服务应用(进阶)
一个 compose.yaml 管好 web、数据库、缓存:自定义网络、健康检查、环境变量、数据卷与重启策略。
单个容器很好起,但真实应用往往是「web + 数据库 + 缓存」的组合。手动 docker run 一个个拉起来既繁琐又容易漏配网络。Docker Compose 用一份声明式的 compose.yaml 把这些服务、网络和数据卷一次性描述清楚,一条命令拉起整套栈。本文假设你在自己的服务器/VPS 上,系统为 Ubuntu/Debian,已装好 Docker Engine 与 Compose 插件(docker compose version 能输出版本即可)。
一个 web + db + redis 的例子
在项目目录新建 compose.yaml:
services:
web:
build: .
ports:
- "8080:8080"
environment:
DATABASE_URL: "postgres://app:${DB_PASSWORD}@db:5432/appdb"
REDIS_URL: "redis://cache:6379"
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
networks:
- backend
restart: unless-stopped
db:
image: postgres:16
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: appdb
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d appdb"]
interval: 5s
timeout: 3s
retries: 5
networks:
- backend
restart: unless-stopped
cache:
image: redis:7
networks:
- backend
restart: unless-stopped
volumes:
db-data:
networks:
backend:
自定义网络让服务互通
networks 段声明了一个自定义桥接网络 backend,三个服务都接入它。同一网络内,Compose 会做服务名 DNS 解析:web 直接用主机名 db、cache 就能访问对方,无需暴露端口到宿主机。只有真正要对外的 web 才用 ports 把 8080 映射出去,db 和 cache 留在内网更安全。
dependson 与 healthcheck
dependson 控制启动顺序,但默认只等容器「启动」,不等它「就绪」。数据库进程起来到能接受连接之间有空窗,所以给 db 加 healthcheck(用 pgisready 探活),再让 web 用 condition: servicehealthy 等数据库真正健康后再启动,避免首次连接被拒。
环境变量与 .env
把密码等配置抽出来。同目录建一个 .env,Compose 会自动读取:
DB_PASSWORD=change-me-in-prod
compose.yaml 里的 ${DBPASSWORD} 会被替换。记得把 .env 加进 .gitignore,别提交到仓库。
数据卷持久化
容器删掉后文件系统就没了,数据库必须挂命名卷:db-data:/var/lib/postgresql/data。卷由 Docker 托管,docker compose down 也不会删,重建容器数据仍在(除非显式 down -v)。
重启策略
restart: unless-stopped 让容器崩溃或服务器重启后自动拉起,但你手动停掉的除外。生产常用它;想崩溃就重试可用 on-failure。
常用命令
docker compose up -d # 后台拉起整套栈
docker compose ps # 查看状态
docker compose logs -f web # 跟踪某个服务日志
docker compose up -d --scale web=3 # 把 web 横向扩到 3 个副本
docker compose down # 停止并删除容器(保留命名卷)
注意 --scale 时不能再给该服务写死 ports 单端口(会冲突),通常前面挂个反向代理或用端口范围。
小结
Compose 的价值是把「多容器怎么协作」写成一份可版本化的文件:自定义网络让服务用名字互访,healthcheck + dependson 保证启动次序,.env 收口配置,命名卷守住数据,restart 提供自愈。掌握 up -d、logs -f、scale 这几条命令,你就能在任何一台 VPS 上稳定地跑起一套多服务应用。