GitLab CI利用Docker多阶段构建的核心是分离构建与运行阶段,通过多个FROM指令定义不同环境,仅复制必要产物到最终镜像,从而减小体积、加速构建并提升安全性。

GitLab CI 利用 Docker 多阶段构建,核心是把“构建”和“运行”彻底分开——构建只在需要的阶段发生,最终镜像里不带编译器、源码、测试工具这些冗余内容。这样既减小体积,又加快构建速度,还提升安全性。
Dockerfile 里明确划分构建与运行阶段
一个典型的多阶段 Dockerfile 至少包含两个 FROM 指令:前一阶段负责编译或打包(比如用 node:18-alpine 或 golang:1.21),后一阶段只保留可执行文件或静态产物(比如用 nginx:alpine 或 alpine:latest)。
- 第一阶段命名(如 AS builder)便于后续引用,例如
COPY --from=builder /app/dist /usr/share/nginx/html - 避免在最终阶段安装构建依赖,比如不要在 runtime 阶段执行
npm install或go build - 使用
--target参数精准控制 CI 中调用哪个阶段,例如docker build --target builder -t myapp:build .
在 .gitlab-ci.yml 中按阶段调度不同构建动作
GitLab CI 的 stages 和 jobs 要和 Dockerfile 的逻辑对齐,让每个 job 只做一件事,并复用中间产物。
使用约定式提交(Conventional Commits)从 Git 历史记录中生成结构化变更日志,支持多种格式、AI 增强型描述以及可自定义的范围……
- 定义清晰的 stages:比如
build、test、package、deploy - 测试 job 可直接运行构建阶段镜像:
docker run myapp:build npm test,无需重新构建 - 打包 job 使用完整构建:
docker build -t myapp:latest .,它会自动复用 builder 阶段缓存 - 用
artifacts或cache在非 Docker 场景下传递产物,但多阶段 Docker 构建中更推荐靠--from直接跨阶段复制
启用 BuildKit 加速构建过程
GitLab CI 默认可能没开 BuildKit,而它能并行处理层、智能跳过未变指令、更好利用构建缓存。
- 在
.gitlab-ci.yml中添加环境变量:DOCKER_BUILDKIT: "1" - 确保 Runner 支持 BuildKit(Docker 20.10+ 且配置正确)
- 配合
docker build --progress=plain查看详细构建日志,定位慢点
结合 dind 服务保障构建隔离与安全
Docker-in-Docker(dind)让每个 CI job 在独立容器里运行 Docker daemon,避免环境污染和权限冲突。
- 在 job 中声明
services: - docker:dind,并设置DOCKER_HOST: tcp://docker:2375 - 用
docker login推送前认证 Registry,凭证通过 CI 变量注入($CI_REGISTRY_USER/$CI_REGISTRY_PASSWORD) - 敏感操作(如部署)设为
when: manual,防止误触发

















