Featured image of post coding 要停服了, 把所有 CI 迁移到 Github 上(服务器无需翻墙)

coding 要停服了, 把所有 CI 迁移到 Github 上(服务器无需翻墙)

coding 要停服了, 把所有 CI 迁移到 Github 上(服务器无需翻墙)

由于网络问题, 在服务器上直接docker pull ghcr.io会有问题, 所以以下的方式我们采用打包镜像然后同步到服务器的方式来解决这个问题.

核心功能定位

概念 技术本质 核心作用 归属
Tag Git 的轻量标签(Lightweight Tag) 标记仓库中的特定提交(如 git tag v1.0.0 Git 原生功能
Release GitHub 的增强型发布管理 基于 Tag 封装可分发版本(含说明/二进制文件等) GitHub 平台功能
Actions GitHub 的 CI/CD 引擎 通过工作流(Workflow)自动化构建、测试、部署 GitHub 平台服务

创建预定义变量

写工作流文件

# tree
├─.github
│  └─workflows
│      └─deploy.yml
├─Dockerfile
## .github/workflows/deploy.yml
name: deploy

on:
  push:
    branches: ['main']

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}
  IMAGE_TAG: ${{ github.run_id }}
  IMAGE_FULL_NAME: ghcr.io/${{ github.repository }}:${{ github.run_id }}
  # !!! 容器名字
  CONTAINER_NAME: test-ci
  # 镜像保存名字
  IMAGE_FILE: ${{ github.run_id }}.tar

jobs:
  build:

    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
      # This is used to complete the identity challenge
      # with sigstore/fulcio when running outside of PRs.
      id-token: write

    steps:
    
      - name: 检出仓库
        uses: actions/checkout@v4
        
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3.0.0

      - name: 登录
        uses: docker/login-action@v3.0.0
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: 提取镜像名
        id: meta
        uses: docker/metadata-action@v5.0.0
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

      - name: 构建镜像并推送
        id: build-and-push
        uses: docker/build-push-action@v5.0.0
        with:
          context: .
          ## 因为网络不好, 所以不能直接 docker pull, 需要打包然后同步到服务器
          push: false
          load: true
          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
      - name: 打包镜像为 tar 文件
        run: |
          docker save -o ${{ env.IMAGE_FILE }} ${{ env.IMAGE_FULL_NAME }}
          du -sh ${{ env.IMAGE_FILE }}
                    
      - name: 同步镜像到服务器
        uses: appleboy/scp-action@v1
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USERNAME }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          port: ${{ secrets.SSH_PORT }}
          source: ${{ env.IMAGE_FILE }}
          target: /tmp/
          
      - name: ssh 部署
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USERNAME }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          port: ${{ secrets.SSH_PORT }}
          script: |
            # 加载 Docker 镜像
            echo ${{ env.CONTAINER_NAME }}
            echo ${{ env.IMAGE_FULL_NAME }}
            docker load -i /tmp/${{ env.IMAGE_FILE }}
            # 清理旧容器
            docker stop ${{ env.CONTAINER_NAME }} &>/dev/null || true
            docker rm -f ${{ env.CONTAINER_NAME }} &>/dev/null || true
            ## 启动容器
            docker run --name ${{ env.CONTAINER_NAME }} --restart=always ${{ env.IMAGE_FULL_NAME }}
            # 清理临时文件
            rm /tmp/${{ env.IMAGE_FILE }}
            echo "Deployment completed successfully!"            
        
本作品采用知识共享署名 4.0 国际许可协议进行许可,转载时请注明原文链接,图片在使用时请保留全部内容,可适当缩放并在引用处附上图片所在的文章链接。