技术指南
Dockerfile 与 Compose:从构建到可回滚发布
拆分 Dockerfile、Compose 基础配置与生产覆盖,完成合并检查、健康验证和回滚准备。
Dockerfile 负责把应用构建成可复现镜像,Compose 负责描述多个容器怎样运行。把二者混成一份“能启动就算完成”的配置,常见结果是源码被生产挂载覆盖、数据库端口意外公开、镜像版本漂移,或更新时连依赖服务一起重建。可靠部署应先固定构建输入,再把开发差异和生产差异显式分层。
先分清三层职责
| 层次 | 应负责的内容 | 不应放入 |
|---|---|---|
| Dockerfile | 运行时、依赖、应用文件、非 root 用户、启动命令 | 密码、生产环境变量、宿主机路径 |
| compose.yaml | 服务、网络、卷、健康检查和默认端口 | 真实密钥、仅生产可用的域名 |
| 生产 override | 镜像标签、重启策略、资源和日志、生产端口 | 开发源码挂载和调试入口 |
构建可追溯镜像
Docker 官方建议选择可信且尽量小的基础镜像,使用多阶段构建隔离编译工具,通过 `.dockerignore` 排除无关文件,并让最终进程以非 root 用户运行。版本标签可读但可能移动;严格环境应记录镜像摘要,并建立定期升级流程,而不是永远冻结旧依赖。
# syntax=docker/dockerfile:1
FROM node:24-bookworm-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:1.28-alpine
COPY --from=build /app/dist /usr/share/nginx/html
USER nginx把生产差异写成 override
保留一个可供开发和测试复用的基础 `compose.yaml`,再用 `compose.production.yaml` 只覆盖生产差异。Docker 官方文档明确列出移除源码绑定、调整端口、降低日志噪声和设置重启策略等生产变化。先检查合并结果,避免“以为被覆盖”但实际仍继承了开发设置。
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 -f compose.yaml -f compose.production.yaml ps验证不是只看容器 Up
- 从真实入口完成一条关键业务请求,确认状态码、响应内容和鉴权。
- 检查健康检查、容器日志、磁盘写入位置和依赖连接;重启后重复。
- 确认数据库、缓存和管理端口没有发布到非预期地址。
- 记录每个运行镜像的标签和摘要,确认部署产物来自本次构建。
小步更新与回滚
单服务更新时,Docker 官方示例使用重新构建目标服务,再以 `--no-deps` 只重建它。这样能减少无关依赖的扰动,但数据库迁移仍要单独设计。发布前保留旧镜像摘要、Compose 文件、配置和可恢复数据;新版本健康检查失败时,切回旧镜像并重新创建目标服务。
docker compose build web
docker compose up --no-deps -d web
docker compose ps
docker compose logs --tail=100 web常见故障路径
- 配置未生效:检查实际使用的 `-f` 顺序和 `config` 合并输出。
- 镜像仍是旧版:比较摘要,确认拉取源、标签和部署主机。
- 容器正常但请求失败:从端口发布、健康检查、服务网络、DNS 和应用日志逐层排查。
- 重建后数据丢失:检查命名卷或绑定目录是否与应用真实写入路径一致。