会用 docker run 起单个容器只是开始。真实应用往往是”应用+数据库+缓存+反代”的组合,用Docker Compose把它们编排成一个整体来管理,才是容器化的正确姿势。本文在Docker入门基础上深入编排、网络、数据卷等进阶话题。
一、Compose的价值:一个文件管理整个应用栈
Docker Compose用一个 docker-compose.yml 文件描述多个容器及其关系,一条命令启停整个栈。好处:配置即代码、可版本管理、迁移换机原样复活(参考博客Docker篇)、多容器依赖关系清晰。
二、容器网络:让容器互相通信
这是多容器应用的关键。Compose默认为一个项目创建一个网络,同一网络内的容器可以用服务名互相访问:
services:
app:
image: myapp
environment:
DB_HOST: db # 直接用服务名"db"连数据库!
db:
image: postgres:16
networks:
default:
name: myapp-net
app容器连数据库,主机名直接写 db(服务名)即可,Compose内置DNS会解析到对应容器。关键安全点:数据库不需要 ports 映射到宿主机——容器间通过内部网络通信,数据库端口不暴露公网,天然安全(参考Redis安全篇)。
三、自定义网络隔离
复杂应用可以用多个网络做隔离,比如让前端和后端在不同网络,数据库只和后端同网:
services:
frontend:
networks: [frontend-net]
backend:
networks: [frontend-net, backend-net]
db:
networks: [backend-net] # db只和backend互通,frontend碰不到
networks:
frontend-net:
backend-net:
这种网络隔离是容器化的安全最佳实践——最小化各容器的可达范围。
四、数据卷:数据持久化
容器是”用完即弃”的,数据必须放在卷里才不会随容器删除而丢失:
services:
db:
image: postgres:16
volumes:
- db_data:/var/lib/postgresql/data # 命名卷,数据持久化
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro # 挂载文件
volumes:
db_data:
命名卷(db_data)由Docker管理,适合数据库;绑定挂载(./目录)映射宿主机路径,适合配置文件和需要直接访问的数据。备份时重点备份这些卷(参考备份篇)。
五、环境变量与密钥管理
services:
app:
env_file: .env # 从文件加载环境变量
environment:
- NODE_ENV=production
敏感信息(密码、密钥)放 .env 文件(加入.gitignore别提交),不硬编码在compose里。生产环境可用Docker secrets进一步保护。
六、健康检查与依赖控制
让应用等数据库真正就绪再启动,避免启动竞态:
services:
db:
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
interval: 10s
retries: 5
app:
depends_on:
db:
condition: service_healthy # 等db健康检查通过
七、常用运维命令
docker compose up -d # 后台启动整个栈
docker compose ps # 查看状态
docker compose logs -f app # 看某服务日志
docker compose restart app # 重启单个服务
docker compose down # 停止并移除(加-v连卷一起删,慎用)
docker compose pull && docker compose up -d # 更新镜像并重建
结论
Docker Compose进阶的精髓:用服务名做容器互联、数据库不映射公网端口、多网络做隔离、数据放命名卷、健康检查控依赖。掌握这些,复杂应用栈的部署、迁移、维护都能优雅可控。在你的香港VPS上用Compose编排一套”应用+数据库+反代”,体会容器化管理的清爽。