能启动只是起点,生产要能解释每个资源
本地 Compose 常包含源码挂载、开发端口、latest 镜像和默认密码,上生产后这些便利会变成不确定性。生产检查不是把 environment 改成 production 就结束,而是回答镜像从哪来、数据在哪、容器如何通信、失败如何发现、版本如何退回。 先保留基础 compose.yaml,再用 compose.production.yaml 覆盖生产差异。这样开发配置与生产配置的边界可审查,不必复制两份逐渐分叉的完整文件。
镜像要可重复获取,不使用漂移的 latest
使用明确版本或不可变 digest,例如 myapp:2026-08-14,而不是每次拉取含义不同的 latest。若在服务器构建,固定基础镜像与锁文件,并确认构建上下文没有把 .env、数据库和备份打进镜像。更稳妥的流程是在受控环境构建并推送,再由服务器拉取同一镜像。 记录镜像 ID 与发布版本。回滚时需要的是上一个已验证镜像,不是重新构建旧代码,因为基础镜像和依赖源可能已经变化。
只把反向代理需要的端口发布到本机
应用由宿主机 Caddy 代理时,可绑定回环地址:
services:
app:
image: registry.example.com/myapp:2026-08-14
ports:
- "127.0.0.1:3000:3000"
restart: unless-stopped数据库不需要 ports,通过 Compose 内部网络用服务名连接。暴露端口与 EXPOSE 不是同一回事,最终用 ss -lntp 和 docker compose ps 核对宿主机实际监听。
持久卷必须能被备份和恢复
列出所有写入位置:数据库、上传、搜索索引、队列和应用生成文件。绑定挂载要明确宿主机路径和权限,命名卷要知道物理数据如何备份。删除容器不应删除数据,但 docker compose down -v 会删除卷,生产手册必须明确禁止随意执行。 把只读配置和持久数据分开挂载。容器以非 root 用户运行时,提前处理目录所有者,不要遇到权限错误就把目录 chmod 777。
健康检查要验证服务能力
进程存在不代表能响应。应用提供轻量 /health,检查关键初始化是否完成,但不要每几秒执行昂贵数据库全表查询。Compose 健康检查设置合理间隔、超时、重试和启动宽限:
healthcheck:
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:3000/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 20s镜像里没有 wget 就换成实际可用工具,不能复制后假装检查生效。依赖启动顺序只能减少竞争,不能替代应用自身重试和错误处理。
先渲染最终配置,再启动
docker compose -f compose.yaml -f compose.production.yaml config
docker compose -f compose.yaml -f compose.production.yaml pull
docker compose -f compose.yaml -f compose.production.yaml up -d
docker compose ps
docker compose logs --tail=100 appconfig 输出会暴露最终端口、卷和变量来源,检查时注意不要把敏感值复制到工单。启动后从本机健康端点、Caddy 域名和关键业务路径三层验证。
更新和回滚都要提前写命令
发布前备份数据,拉取新版本,启动后等待健康,再切换或继续服务。失败时把镜像标签改回上一版并重新 up,而不是现场查 Git 提交再构建。数据库迁移必须评估向后兼容,无法回滚的数据变更需要先扩展、后切换、最后清理。 完成标准是:镜像不可变、公开端口最少、持久数据有清单、健康检查真实可用、最终配置经过查看、上一版镜像仍可取回。下一篇专门处理最容易被复制进仓库和日志的部分:生产环境密钥管理。