# 在 CI 中构建与推送镜像

URL: https://caijiao.org/docker/cicd/build-and-push
Source: docs/docker/cicd/build-and-push.md
Description: 本章节介绍在持续集成（CI）环境中自动构建和推送 Docker 镜像的方法，包括使用 GitHub Actions、GitLab CI 或 Jenkins，实现镜像自动化管理与部署。

将 Docker 镜像构建与推送集成到 CI/CD 流程中，可以实现持续集成与自动部署，提升开发效率和发布可靠性。

## 1. 基本流程

1. **拉取代码**：CI 工具拉取仓库代码
2. **构建镜像**：使用 `docker build` 创建镜像
3. **标记镜像**：使用版本号或 Git commit 作为标签
4. **登录镜像仓库**：Docker Hub 或私有 Registry
5. **推送镜像**：将镜像推送到远程仓库

## 2. 使用 GitHub Actions 示例

```yaml
name: Docker Build & Push

on:
  push:
    branches:
      - main

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Log in to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build and push
        uses: docker/build-push-action@v4
        with:
          context: .
          push: true
          tags: myusername/myapp:latest
````

## 3. 使用 GitLab CI 示例

```yaml
stages:
  - build

build_and_push:
  stage: build
  image: docker:20.10.16
  services:
    - docker:dind
  script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
    - docker build -t $CI_REGISTRY_IMAGE:latest .
    - docker push $CI_REGISTRY_IMAGE:latest
```

## 4. Jenkins Pipeline 示例

```groovy
pipeline {
    agent any
    environment {
        DOCKER_CREDENTIALS = 'docker-hub-cred'
        IMAGE_NAME = 'myusername/myapp'
    }
    stages {
        stage('Build') {
            steps {
                checkout scm
                script {
                    docker.build("${IMAGE_NAME}:latest")
                }
            }
        }
        stage('Push') {
            steps {
                script {
                    docker.withRegistry('', DOCKER_CREDENTIALS) {
                        docker.image("${IMAGE_NAME}:latest").push()
                    }
                }
            }
        }
    }
}
```

## 5. 最佳实践

* 使用 CI 工具的 Secret 管理镜像仓库凭证
* 给镜像打上版本号或 Git commit 标签，避免覆盖历史镜像
* 构建阶段尽量缓存依赖，提升构建速度
* 在多阶段构建中，仅将运行环境拷贝到最终镜像，减小体积

---

通过将 Docker 镜像构建与推送集成到 CI/CD 流程，实现镜像自动化管理，提高应用交付效率与可靠性。
