宁语之溪 - Docker Compose
type: channel
link: https://nyzx.de/tag/docker-compose/
items: Docker Compose 如何编排一套微服务系统

Docker Compose 如何编排一套微服务系统
type: item
date: 2026-02-28T16:39:00+08:00
description: 一套微服务系统不只有业务服务，还包括数据库、缓存、注册中心、对象存储、消息队列和监控组件。手工逐个启动容易遗漏配置，也很难保证其他环境按照同样方式复现。在 HAOVP 的开发和单机部署中，我使用 Docker Compose 描述服务、网络、数据卷、环境变量和启动依赖。Compose 的价值是让一组容器可以统一启动和管理，但单机编排本身不等于高可用集群。Compose 文件描述什么一个 Compose 文件通常包含：services networks volumes configs 或 secrets（按实际环境）services 定义容器；networks 定义容器间通信；volumes 保存持久化数据；配置和秘密则需要通过受控方式提供。一个简化示例：services: gateway: image: example/gateway:latest env_file: - .env networks: - app-network depends_on: registry: condition: service_healthy networks: app-network: driver: bridge镜像名、文件名和服务名均为通用示例，不对应真实部署配置。先区分基础设施和业务服务我会把服务按职责整理：数据库和缓存；注册中心与配置中心；对象存储和消息队列；网关；认证、用户、内容、评论、推荐和管理服务；用户端与管理端；监控和日志组件。分组不一定要拆成多个文件，但需要看清依赖关系。基础设施没有就绪时，业务服务即使进程启动，也可能立即连接失败。depends_on 不保证业务可用Compose 的 depends_on 可以控制启动顺序，配合健康检查等待依赖达到健康状态。healthcheck: test: ["CMD", "sh", "-c", "check-command"] interval: 10s timeout: 5s retries: 10这是结构示例。健康检查命令应针对实际组件设计，不公开真实账号和地址。容器状态为 running 不等于服务可用；健康检查通过也不等于完整业务链路可用。业务服务仍需要重试、超时和明确的启动失败日志。容器间通过服务名通信同一 Compose 网络中的服务可以使用服务名访问彼此，不需要写死容器 IP。业务服务 -> mysql-service 业务服务 -> redis-service Gateway -> registry-service容器 IP 可能随重建变化，服务名更稳定。对外暴露端口与容器内部端口也要区分：容器间通信通常使用内部端口，只有真正需要从宿主机访问的服务才映射端口。公开文档不应包含真实宿主机地址、内部域名和生产端口表。环境变量和秘密分开处理Compose 文件可以引用环境变量，但不能把密码和密钥直接提交到仓库。environment: DB_HOST: ${DB_HOST} DB_NAME: ${DB_NAME} DB_PASSWORD: ${DB_PASSWORD}变量名称可以进入文档，真实值不能进入公开文件、镜像层和启动日志。我会检查：.env 是否被版本控制忽略；示例文件是否只包含占位值；容器日志是否打印完整环境；默认密码是否已替换；不同环境是否使用独立配置；Secret 更新后如何重启和验证。数据卷决定数据是否保留数据库、Redis 持久化、Nacos 数据和 MinIO 对象不能只依赖容器可写层。容器删除后，可写层也会消失。volumes: mysql-data: object-data:数据卷还需要考虑：备份与恢复；权限；磁盘容量；升级兼容性；错误挂载；删除 Compose 项目时是否保留。docker compose down -v 会删除声明的数据卷，不能在不确认数据范围时执行。镜像要可追踪长期使用 latest 会让同一 Compose 文件在不同时间拉到不同镜像，不利于复现。更稳妥的方式是使用明确版本或镜像摘要，并记录：源代码版本；构建时间；镜像标签；配置版本；数据库迁移版本。业务服务升级时，先确认数据库和接口兼容，再决定启动顺序和回滚方式。服务启动顺序一套简化顺序可以是：网络与数据卷 -> 数据库、缓存、对象存储、消息队列 -> 注册与配置中心 -> 业务服务 -> 网关 -> 前端与监控实际启动可以并行，但依赖必须具备重试和健康检查。某个服务首次连接失败后直接退出，会让整个启动过程变得脆弱。日志和可观测性Compose 可以统一查看日志：docker compose logs -f --tail=200 gateway命令中的服务名是示例。我会关注：日志是否带服务名和请求标识；是否限制日志大小和保留时间；错误日志能否定位依赖；是否泄露 Token、密…