技术指南

Dockerfile 与 Compose:从构建到可回滚发布

拆分 Dockerfile、Compose 基础配置与生产覆盖,完成合并检查、健康验证和回滚准备。

Dockerfile 负责把应用构建成可复现镜像,Compose 负责描述多个容器怎样运行。把二者混成一份“能启动就算完成”的配置,常见结果是源码被生产挂载覆盖、数据库端口意外公开、镜像版本漂移,或更新时连依赖服务一起重建。可靠部署应先固定构建输入,再把开发差异和生产差异显式分层。

先分清三层职责

层次应负责的内容不应放入
Dockerfile运行时、依赖、应用文件、非 root 用户、启动命令密码、生产环境变量、宿主机路径
compose.yaml服务、网络、卷、健康检查和默认端口真实密钥、仅生产可用的域名
生产 override镜像标签、重启策略、资源和日志、生产端口开发源码挂载和调试入口

构建可追溯镜像

Docker 官方建议选择可信且尽量小的基础镜像,使用多阶段构建隔离编译工具,通过 `.dockerignore` 排除无关文件,并让最终进程以非 root 用户运行。版本标签可读但可能移动;严格环境应记录镜像摘要,并建立定期升级流程,而不是永远冻结旧依赖。

示意 Dockerfile;基础版本、运行用户和构建命令必须按项目核对
# 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 官方文档明确列出移除源码绑定、调整端口、降低日志噪声和设置重启策略等生产变化。先检查合并结果,避免“以为被覆盖”但实际仍继承了开发设置。

先审阅 config 输出,再拉取、部署和查看状态
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 文件、配置和可恢复数据;新版本健康检查失败时,切回旧镜像并重新创建目标服务。

示例服务名 web;部署前替换并确认依赖关系
docker compose build web
docker compose up --no-deps -d web
docker compose ps
docker compose logs --tail=100 web

常见故障路径

  • 配置未生效:检查实际使用的 `-f` 顺序和 `config` 合并输出。
  • 镜像仍是旧版:比较摘要,确认拉取源、标签和部署主机。
  • 容器正常但请求失败:从端口发布、健康检查、服务网络、DNS 和应用日志逐层排查。
  • 重建后数据丢失:检查命名卷或绑定目录是否与应用真实写入路径一致。

返回知识库