在前几篇中,我们已经完成了从 Docker 基础、镜像与缓存、网络与数据卷、容器编排(Swarm / Kubernetes) 的系统学习。
但在真实的生产环境中,Docker 并不是手动运行的。
真正的价值在于:
代码一提交,自动构建镜像、自动测试、自动发布、自动回滚。
这一篇,我们把 Docker 放进 CI/CD 流水线,完整走一遍:
从一次 Git 提交开始,到服务自动部署上线。
一、为什么 Docker 是 CI/CD 的天然载体
在没有 Docker 之前,CI/CD 经常会遇到这些问题:
- CI 环境和生产环境不一致
- 构建机缺少依赖、版本不统一
- “在我机器上能跑”的经典问题
- 回滚复杂、发布不可追溯
而 Docker 天生解决了这些痛点。
Docker 在 CI/CD 中的核心价值
| 能力 | 说明 |
|---|---|
| 环境一致性 | 镜像即环境,CI / 测试 / 生产完全一致 |
| 构建可复现 | 同一个 Dockerfile 构建结果稳定 |
| 发布标准化 | 发布的不是代码,而是镜像 |
| 回滚简单 | 镜像版本回退即可 |
| 与编排天然结合 | Swarm / K8s 直接部署 |
CI/CD 的终点不是“跑脚本”,而是“交付镜像”。
二、一个完整的 Docker CI/CD 流水线长什么样
我们先看整体流程,不纠结工具。
标准流程图(简化版)
Git Commit
↓
CI 触发
↓
代码拉取
↓
Docker 镜像构建
↓
单元测试 / 构建校验
↓
镜像推送(Registry)
↓
CD 部署(Swarm / K8s)
↓
健康检查
核心思想:
- CI 阶段:产出镜像
- CD 阶段:部署镜像
三、示例项目结构
以一个典型的前端 / Node 服务为例:
project/
├── src/
├── package.json
├── Dockerfile
├── docker-compose.yml
├── .dockerignore
└── .ci/
└── pipeline.yml
四、Dockerfile:CI/CD 的核心契约
一个适合 CI/CD 的 Dockerfile,必须做到三点:
- 构建速度快
- 层缓存友好
- 产物干净、安全
示例:多阶段构建(Node)
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
# 利用缓存
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
# 运行阶段
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
为什么这对 CI/CD 很重要?
npm ci保证依赖可复现- 构建和运行环境隔离
- 最终镜像体积小
- 构建失败立即中断流水线
五、CI 阶段:自动构建并推送 Docker 镜像
无论你用什么 CI(GitHub Actions / GitLab CI / Jenkins),核心步骤是一样的。
通用 CI 步骤拆解
- 登录镜像仓库
- 构建镜像
- 打 tag
- 推送镜像
示例:CI 脚本核心逻辑
# 登录镜像仓库
docker login registry.example.com -u $USERNAME -p $PASSWORD
# 构建镜像
docker build -t registry.example.com/my-app:${CI_COMMIT_SHA} .
# 推送镜像
docker push registry.example.com/my-app:${CI_COMMIT_SHA}
推荐的镜像 Tag 策略
| 场景 | Tag |
|---|---|
| 精确回溯 | commit SHA |
| 测试环境 | dev / test |
| 生产环境 | v1.2.3 |
| 最新稳定 | latest(慎用) |
不要只用 latest,这是 CI/CD 的反模式。
六、CD 阶段:基于镜像的自动部署
1️⃣ Docker Swarm 部署示例
docker service update \
--image registry.example.com/my-app:${CI_COMMIT_SHA} \
my-app-service
Swarm 会自动完成:
- 滚动更新
- 旧容器下线
- 新容器健康检查
2️⃣ Kubernetes 部署示例
kubectl set image deployment/my-app \
my-app=registry.example.com/my-app:${CI_COMMIT_SHA}
或者使用 YAML:
spec:
containers:
- name: my-app
image: registry.example.com/my-app:v1.2.3
七、CI/CD 中的 Docker 最佳实践
1️⃣ 构建速度优化
- 使用
.dockerignore - 合理拆分 COPY 顺序
- 多阶段构建
- 使用缓存镜像
2️⃣ 安全建议
- 不在镜像中存密钥
- 使用 CI 的 Secret 管理
- 运行阶段用非 root 用户
- 定期扫描镜像漏洞
3️⃣ 回滚策略
回滚 = 切回旧镜像
kubectl rollout undo deployment/my-app
或:
docker service update --rollback my-app-service
八、Docker + CI/CD 的典型架构组合
| CI/CD 工具 | Docker | 编排 |
|---|---|---|
| GitHub Actions | ✔ | K8s |
| GitLab CI | ✔ | Swarm / K8s |
| Jenkins | ✔ | 任意 |
| Argo CD | ✔ | K8s |
趋势很明确:
CI 负责构建
CD 负责部署
Docker 是中间的交付物
九、从“能跑”到“可持续交付”的关键转变
很多团队的问题不在工具,而在认知:
❌ 把 CI/CD 当脚本
❌ 把 Docker 当运行工具
❌ 发布依赖人工确认
正确的方式是:
✅ 镜像是唯一交付物
✅ 环境由 Docker 定义
✅ 发布由系统驱动
十、总结
这一篇我们完成了 Docker 进阶中非常关键的一环:
让 Docker 真正进入工程体系,而不是停留在命令行。
你现在应该已经具备:
- 用 Docker 作为 CI/CD 构建产物
- 将镜像作为发布与回滚的最小单元
- 在 Swarm / Kubernetes 中自动部署
文章评论