2025-10-27
计算机基础
0

目录

步骤 1:准备工作
步骤 2:创建 GitHub Actions 工作流文件
关键配置说明
步骤 3:测试工作流
注意:如果有多个镜像也可使用docker-compose构建
补充:自动更新latest标签
核心思路
修改工作流配置

要使用 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

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

yaml
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

yml
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)

yml
# 构建镜像(基于基础标签) - 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,重点调整 镜像标签生成推送逻辑

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

本文作者:司小远

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!