# LandPPT Docker Build & Push Workflow # 自动构建并推送 Docker 镜像到容器注册表 name: Docker Build and Push on: # 在 main 分支推送时触发 push: branches: - main - master # 仅当以下文件变更时触发 paths: - 'Dockerfile' - 'docker-compose.yml' - 'docker-entrypoint.sh' - 'docker-healthcheck.sh' - 'src/**' - 'pyproject.toml' - 'uv.lock' - '.github/workflows/docker-build.yml' # 在 PR 时进行构建测试(不推送) pull_request: branches: - main - master # 手动触发 workflow_dispatch: inputs: push_image: description: '是否推送镜像到注册表' required: false default: 'true' type: boolean env: # Docker 镜像名称 - 请根据实际情况修改 IMAGE_NAME: landppt # 构建平台 PLATFORMS: linux/amd64 jobs: build: name: Build Docker Image runs-on: ubuntu-latest permissions: contents: read packages: write steps: # 检出代码 - name: Checkout Repository uses: actions/checkout@v4 # 清理磁盘空间(防止构建时空间不足) - name: Free Disk Space run: | sudo rm -rf /usr/share/dotnet sudo rm -rf /usr/local/lib/android sudo rm -rf /opt/ghc sudo rm -rf /opt/hostedtoolcache/CodeQL sudo docker system prune -af df -h # 设置 Docker Buildx(用于高级构建功能) - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 # 登录到 GitHub Container Registry (ghcr.io) - name: Login to GitHub Container Registry if: github.event_name != 'pull_request' uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} # 登录到 Docker Hub(可选 - 如果需要推送到 Docker Hub) # 需要在 Repository Settings > Secrets 中设置 DOCKERHUB_USERNAME 和 DOCKERHUB_TOKEN - name: Login to Docker Hub if: github.event_name != 'pull_request' uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} continue-on-error: true # 提取 Docker 元数据(标签、标签等) - name: Extract Docker Metadata id: meta uses: docker/metadata-action@v5 with: images: | ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_NAME }} ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }} tags: | # 最新标签(仅在 main/master 分支) type=raw,value=latest,enable={{is_default_branch}} # Git 短 SHA type=sha,prefix= # 分支名称 type=ref,event=branch # PR 编号 type=ref,event=pr # 语义化版本(如果有标签) type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} # 日期标签 type=raw,value={{date 'YYYYMMDD-HHmmss'}} # 构建并推送 Docker 镜像 - name: Build and Push Docker Image uses: docker/build-push-action@v5 with: context: . file: ./Dockerfile platforms: ${{ env.PLATFORMS }} # PR 时不推送,仅构建验证 push: ${{ github.event_name != 'pull_request' && (github.event.inputs.push_image != 'false') }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} # 利用 GitHub Actions 缓存加速构建 cache-from: type=gha cache-to: type=gha,mode=max # 构建参数(如需要可添加) build-args: | BUILDTIME=${{ github.event.repository.updated_at }} VERSION=${{ github.sha }} # 输出镜像摘要 - name: Image Digest run: | echo "### Docker Image Built Successfully! :rocket:" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "**Image Tags:**" >> $GITHUB_STEP_SUMMARY echo "\`\`\`" >> $GITHUB_STEP_SUMMARY echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY echo "\`\`\`" >> $GITHUB_STEP_SUMMARY # 安全扫描(可选但推荐) security-scan: name: Security Scan runs-on: ubuntu-latest needs: build if: github.event_name != 'pull_request' steps: - name: Checkout Repository uses: actions/checkout@v4 # 使用 Trivy 扫描 Dockerfile 漏洞 - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: scan-type: 'config' scan-ref: '.' format: 'sarif' output: 'trivy-results.sarif' continue-on-error: true # 上传扫描结果到 GitHub Security - name: Upload Trivy scan results uses: github/codeql-action/upload-sarif@v3 with: sarif_file: 'trivy-results.sarif' continue-on-error: true