Dockerfile 与 Docker Compose 在 CI/CD 管道中的分工与配合方式

一、基础回顾(快速过一遍)

Dockerfile docker-compose.yml
目标 构建一个可移植、可复现的镜像 描述并管理多个容器如何一起运行
产出 镜像 image 容器、网络、卷、配置
生命周期 构建时(Build Time) 运行时(Runtime),本地开发 + 测试环境首选
典型命令 docker build docker compose up / down / logs

二、它们在不同场景下的职责完全不同

场景 必须用 Dockerfile ? 必须用 Compose ? 说明
本地开发运行单服务 直接 docker run 就行
本地开发完整系统 强烈推荐 用 Compose 一键启动 MySQL、Redis、Nginx 等
测试环境(Testing) 推荐 测试经常用 Compose 快速拉起全套依赖
生产环境(Production) 一般不用 生产用 Kubernetes、Docker Swarm、ECS、Nomad、CloudRun 等编排工具

三、CI/CD 中它们到底怎么配合?(核心重点)

真实生产级 CI/CD 流程是这样的:

复制代码
代码提交 
   ↓
GitHub Actions / GitLab CI Jenkins 等
   ↓
1. 单元测试 + 静态检查
   ↓
2. 用 Dockerfile 构建镜像 ← 这里用 Dockerfile
   ↓
3. 把镜像推到镜像仓库(Harbor、ECR、GHCR、Docker Hub)
   ↓
   ├─→ 4a. 测试/预发布环境:用 docker-compose.yml 拉起全套服务做集成测试
   └─ 4b. 生产环境:Kubernetes 用 Helm Chart 或 K8s Manifest 部署(不使用 Compose)

详细拆解每个阶段:

阶段 1:构建阶段(必须用 Dockerfile)
复制代码
# GitHub Actions 示例片段
- name: Build and push Docker image
  uses: docker/build-push-action@v5
  with:
    context: .
    file: ./Dockerfile              # ← 必须有
    push: true
    tags: mycompany/myapp:${{ github.sha }}, mycompany/myapp:latest

这一步只认 Dockerfile,Compose 完全不参与。

阶段 2:集成测试/预发布环境(强烈推荐用 docker-compose.yml)
复制代码
- name: Start services with Docker Compose
  run: docker compose -f docker-compose.ci.yml up -d

- name: Run integration tests
  run: npm run test:integration

- name: Stop services
  if: always()
  run: docker compose -f docker-compose.ci.yml down -v

常见的 docker-compose.ci.yml 会比本地开发版更严格:

复制代码
version: '3.9'
services:
  app:
    image: mycompany/myapp:${{ github.sha }}   # 直接用刚刚构建的镜像,不再 build
    environment:
      - NODE_ENV=test
    depends_on:
      mysql:
        condition: service_healthy

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: testdb
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 5s
      timeout: 5s
      retries: 10

  redis:
    image: redis:7-alpine
阶段 3:生产部署(完全抛弃 docker-compose)

生产环境几乎没人直接用 docker compose up 上生产!常见方案:

  • Kubernetes(95% 大厂选择)→ 用 Helm Chart 或 kubectl apply
  • Docker Swarm(少量)
  • 云厂商托管容器服务:阿里云 ACK、AWS ECS Fargate、腾讯云 TKE、Google Cloud Run 等

生产部署通常会把镜像标签改成固定版本:

复制代码
# Helm values-prod.yaml 片段
image:
  repository: mycompany/myapp
  tag: "v1.3.2"    # 或 ${{ github.sha }}

四、生产级项目目录结构最佳实践

复制代码
my-project/
├── Dockerfile                  # 构建生产镜像(多阶段构建)
├── Dockerfile.dev              # 可选:本地开发专用轻量镜像
├── docker-compose.yml          # 本地开发用
├── docker-compose.override.yml  # 本地覆盖(IDE 自动生成)
├── docker-compose.ci.yml       # CI 专用(无卷、更严格)
├── docker-compose.prod.yml     # 几乎没人用,生产不用 Compose
├── k8s/                        # 或 helm-chart/
│   ├── deployment.yaml
│   ├── service.yaml
│   └── ingress.yaml
└── src/

五、进阶:多阶段构建 + Compose 配合示例

复制代码
# Dockerfile(生产推荐多阶段)
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY package*.json ./
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "dist/index.js"]

CI 中可以额外加一个 dev 阶段用于本地:

复制代码
# docker-compose.yml 本地开发
services:
  app:
    build:
      context: .
      target: builder               # 只构建到 builder 阶段,热重载快
    volumes:
      - .:/app
      - /app/node_modules
    ports:
      - "3000:3000"
    command: npm run dev

六、总结:一句话记住分工

  • Dockerfile 是"造车工厂 → 负责生产"标准零件"(镜像),CI/CD 全程必须用到
  • docker-compose.yml 是本地试车场 → 只在开发者本地、测试/CI 环境使用,生产环境基本不用

正确姿势是:

本地开发 → docker-compose.yml + Dockerfile CI/CD 构建 → 只用 Dockerfile 打镜像 集成测试 → 用 docker-compose.yml 拉依赖 生产部署 → 用 Kubernetes/云服务,完全丢掉 Compose

这样才算真正玩明白了 Docker 的精髓!

相关推荐
努力搬砖的咸鱼5 分钟前
部署你的第一个应用到 K8s
微服务·云原生·容器·kubernetes
lpruoyu44 分钟前
【Docker进阶-01】Docker隔离原理与可视化界面-Portainer
docker
舰长1151 小时前
使用 kubeadm搭建生产环境的单 master 节点 K8S 集群(一)
云原生·容器·kubernetes
Swift社区2 小时前
Docker 构建 Python FastAPI 镜像最佳实践
python·docker·fastapi
API开发2 小时前
CentOS 单独安装Docker Compose v2
linux·docker·centos·docker compose
hwj运维之路2 小时前
Docker面试题汇总系列
运维·docker·云原生·容器
chao_7892 小时前
双设备全栈开发最佳实践[mac系统]
git·python·macos·docker·vue·全栈
搬砖者(视觉算法工程师)3 小时前
简单介绍Docker:Docker 容器中预装 Ubuntu 20.04 与 ROS Noetic
docker
张小凡vip3 小时前
Kubernetes---gitlab的ci/cd发布基于k8s的项目示例参考
ci/cd·kubernetes·gitlab
VermiliEiz3 小时前
使用二进制方式部署k8s(6)
云原生·容器·kubernetes