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 的精髓!

相关推荐
牛奔1 天前
Docker Compose 解决服务间 DNS 解析失败问题
运维·docker·容器
L1624761 天前
Docker 安装部署全流程使用指南(Linux 通用版)
linux·docker·容器
Mr. Cao code1 天前
MySQL数据卷实战:持久化存储秘籍
数据库·mysql·docker·容器
卓码软件测评1 天前
软件首版次认定测试机构:【Apifox与UMI框架结合:实现OpenAPI规范与Mock服务的自动化流水线】
测试工具·ci/cd·性能优化·单元测试·测试用例
桂花树下的猫1 天前
ubuntu20.04上docker部署
运维·docker·容器
自不量力的A同学1 天前
Docker 29.1.4
运维·docker·容器
黯叶1 天前
基于 Docker+Docker-Compose 的 SpringBoot 项目标准化部署(外置 application-prod.yml 配置方案)
java·spring boot·redis·docker
木童6621 天前
K8s 组网方案深度解析:Flannel vs Calico 原理与选型
云原生·容器·kubernetes
魂之木1 天前
【零基础教程】基于Docker的RabbitMQ部署方案
分布式·docker·微服务·rabbitmq
星哥说事1 天前
零成本上线!用 Hugging Face免费服务器+Docker 快速部署HertzBeat 监控平台
运维·服务器·docker