告别手动打包!GitHub Actions 帮你自动推送 Docker 镜像到 Docker Hub

要使用 GitHub Actions 自动打包 Docker 镜像并上传到 Docker Hub,可按以下步骤操作,通过配置工作流文件实现自动化流程:

步骤 1:准备工作

  1. Docker Hub 账号
    确保拥有 Docker Hub 账号,并创建一个仓库(如 username/your-image-name)。

  2. GitHub 仓库
    将项目代码推送到 GitHub 仓库,确保代码中包含 Dockerfile(用于构建镜像)。

  3. 配置 Docker Hub 凭据
    在 GitHub 仓库的 Settings → Secrets and variables → Actions → New repository secret 中添加两个密钥:

    • DOCKER_HUB_USERNAME:Docker Hub 用户名
    • DOCKER_HUB_ACCESS_TOKEN:Docker Hub 访问令牌(在 Docker Hub 账号设置 中生成,需勾选 write 权限)

步骤 2:创建 GitHub Actions 工作流文件

在 GitHub 仓库中创建工作流配置文件,路径为:
.github/workflows/docker-build-push.yml

文件内容如下(可根据需求调整):

name: Build and Push Docker Image

# 触发条件:当推送到 main 分支或创建标签时执行
on:
  push:
    branches: [ "main" ]
    tags: [ "v*.*.*" ]  # 匹配类似 v1.0.0 的标签

jobs:
  build-and-push:
    runs-on: ubuntu-latest  # 使用 Ubuntu 环境
    steps:
      # 步骤 1:拉取 GitHub 仓库代码
      - name: Checkout code
        uses: actions/checkout@v4

      # 步骤 2:设置 Docker 构建环境
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      # 步骤 3:登录 Docker Hub
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_HUB_USERNAME }}
          password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

      # 步骤 4:提取镜像标签(支持分支和标签触发)
      - name: Extract metadata (tags, labels)
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ secrets.DOCKER_HUB_USERNAME }}/your-image-name  # 替换为你的 Docker Hub 仓库名
          tags: |
            type=ref,event=branch  # 分支触发时,标签为分支名(如 main)
            type=semver,pattern={{version}}  # 标签触发时,标签为版本号(如 v1.0.0 → 1.0.0)
            type=semver,pattern={{major}}.{{minor}}  # 标签触发时,额外添加主版本标签(如 1.0)

      # 步骤 5:构建并推送 Docker 镜像
      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: .  # Dockerfile 所在目录(当前目录)
          push: true  # 推送镜像到 Docker Hub
          tags: ${{ steps.meta.outputs.tags }}  # 使用步骤 4 生成的标签
          labels: ${{ steps.meta.outputs.labels }}  # 附加元数据标签
关键配置说明
  1. 触发条件(on
    示例中配置了推送到 main 分支或创建 v*.*.* 格式的标签时触发工作流,可根据需求修改(如添加 pull_request 触发)。

  2. 镜像标签(tags
    通过 docker/metadata-action 自动生成标签:

    • 推送到 main 分支时,标签为 main(方便测试环境使用)。
    • 推送标签 v1.0.0 时,生成标签 1.0.01.0(方便生产环境指定版本)。
  3. 构建上下文(context
    默认为当前目录(.),若 Dockerfile 在子目录(如 ./docker),需修改为 context: ./docker 并通过 file: ./docker/Dockerfile 指定路径。

步骤 3:测试工作流

  1. 将配置文件提交到 GitHub 仓库的 main 分支。

  2. 触发工作流:

    • 推送代码到 main 分支,工作流会自动运行并推送 main 标签的镜像。
    • 创建并推送标签(如 git tag v1.0.0 && git push origin v1.0.0),工作流会推送 1.0.01.0 标签的镜像。
  3. 在 GitHub 仓库的 Actions 标签页中查看工作流运行状态,成功后可在 Docker Hub 仓库中看到推送的镜像。

注意:如果有多个镜像也可使用docker-compose构建

例如,项目根目录下有个docker-composr.yml文件,其作用是从子目录里分别构建两个镜像siyuan044/timelesstales-backend和siyuan044/timelesstales-frontend

version: '3.8'

services:
  backend:
    build: ./package/server
    # 用环境变量 ${TAG} 动态指定版本(默认 fallback 到 v0.1.0)
    image: siyuan044/timelesstales-backend:${TAG:-v0.1.0}
    restart: always
    expose: [ "8000" ]
    networks: [ app-network ]
    volumes: [ "./package/server/data:/app/data" ]

  frontend:
    build: ./package/website
    image: siyuan044/timelesstales-frontend:${TAG:-v0.1.0}
    restart: always
    ports: [ "8081:80" ]
    depends_on: [ backend ]
    networks: [ app-network ]

networks:
  app-network:
    driver: bridge

此时可以使用 docker compose build命令构建镜像(注意部署docker-compose build)

      # 构建镜像(基于基础标签)
      - name: Build images with docker compose
        run: |
          TAG=${{ env.BASE_TAG }} docker compose build

补充:自动更新latest标签

当创建新的 Tag 时(如 v1.0.1),希望同时将 latest 标签指向该最新版本的镜像,可以在推送时额外添加 latest 标签。以下是具体实现方案,确保每次发布新 Tag 时,latest 会自动更新为该版本。

核心思路
  1. 当工作流由 Tag 触发 时(如 v1.0.1),除了推送 1.0.1 标签的镜像,额外推送 latest 标签的镜像。
  2. 当由 分支触发 时(如 main),仅推送分支标签(不影响 latest,避免开发版本覆盖正式版)。
修改工作流配置

更新 .github/workflows/docker-compose-build-push.yml,重点调整 镜像标签生成推送逻辑

name: Build and Push Multi Docker Images with Compose

on:
  push:
    branches: [ "main" ]
    tags: [ "v*.*.*" ]

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Docker
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_HUB_USERNAME }}
          password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

      # 步骤:生成基础标签和额外标签(如 latest)
      - name: Determine image tags
        id: set-tags
        run: |
          # 基础标签(分支名或 Tag 版本)
          if [[ $GITHUB_REF == refs/tags/* ]]; then
            BASE_TAG=${GITHUB_REF#refs/tags/v}  # 如 v1.0.1 → 1.0.1
            EXTRA_TAGS="latest"  # Tag 触发时,额外添加 latest 标签
          else
            BASE_TAG=${GITHUB_REF#refs/heads/}  # 如 main 分支 → main
            EXTRA_TAGS=""  # 分支触发时,不添加 latest
          fi
          # 组合所有标签(用逗号分隔,供后续推送)
          ALL_TAGS="$BASE_TAG"
          if [ -n "$EXTRA_TAGS" ]; then
            ALL_TAGS="$BASE_TAG,$EXTRA_TAGS"
          fi
          # 输出环境变量(后端和前端镜像名相同,仅标签变化)
          echo "BASE_TAG=$BASE_TAG" >> $GITHUB_ENV
          echo "ALL_TAGS=$ALL_TAGS" >> $GITHUB_ENV

      # 构建镜像(基于基础标签)
      - name: Build images with docker compose
        run: |
          TAG=${{ env.BASE_TAG }} docker compose build

      # 推送镜像(包含所有标签:基础标签 + latest(若有))
      - name: Push backend images
        run: |
          # 拆分标签并逐个推送(或用 docker tag 批量处理)
          IFS=',' read -ra TAGS <<< "${{ env.ALL_TAGS }}"
          for TAG in "${TAGS[@]}"; do
            # 先给镜像打多标签,再推送
            docker tag ${{ secrets.DOCKER_HUB_USERNAME }}/timelesstales-backend:${{ env.BASE_TAG }} ${{ secrets.DOCKER_HUB_USERNAME }}/timelesstales-backend:$TAG
            docker push ${{ secrets.DOCKER_HUB_USERNAME }}/timelesstales-backend:$TAG
          done

      - name: Push frontend images
        run: |
          IFS=',' read -ra TAGS <<< "${{ env.ALL_TAGS }}"
          for TAG in "${TAGS[@]}"; do
            docker tag ${{ secrets.DOCKER_HUB_USERNAME }}/timelesstales-frontend:${{ env.BASE_TAG }} ${{ secrets.DOCKER_HUB_USERNAME }}/timelesstales-frontend:$TAG
            docker push ${{ secrets.DOCKER_HUB_USERNAME }}/timelesstales-frontend:$TAG
          done
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值