GitHub 容器镜像(GitHub Container Registry)详解 一、GitHub 容器镜像服务总览 1. GitHub 提供的容器服务 1 2 3 4 5 6 7 8 9 GitHub 容器生态系统: ┌─────────────────────────────────────────────────────┐ │ GitHub Container Registry │ ← 容器镜像仓库 │ (ghcr.io) │ ├─────────────────────────────────────────────────────┤ │ GitHub Actions │ ← CI/CD 流水线 ├─────────────────────────────────────────────────────┤ │ GitHub Packages │ ← 包管理(包括容器) └─────────────────────────────────────────────────────┘
2. GitHub Container Registry (GHCR) 特点 核心优势:
✅ 完全免费 (有一定限制)
✅ 与 GitHub 深度集成
✅ 支持私有和公共镜像
✅ 自动安全扫描
✅ 地理冗余存储
免费额度(个人账户/组织):
1 2 3 4 存储: 500 MB 免费 数据传输: 每月 1 GB 免费 ↓ 超出部分才收费,小项目完全够用
二、三种创建容器镜像的方式 方式1:使用 GitHub Actions 自动构建(推荐) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 name: Build and Push Docker Image on: push: branches: [ main ] tags: [ 'v*' ] pull_request: branches: [ main ] env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: build-and-push: runs-on: ubuntu-latest permissions: contents: read packages: write steps: - name: Checkout repository uses: actions/checkout@v4 - name: Log in to GHCR uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Extract metadata id: meta uses: docker/metadata-action@v5 with: images: ghcr.io/${{ github.repository }} tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=sha,prefix={{branch}}- - name: Build and push uses: docker/build-push-action@v5 with: context: . push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max
方式2:本地构建后手动推送 1 2 3 4 5 6 7 8 9 10 11 docker build -t ghcr.io/your-username/your-image:latest . echo "你的个人访问令牌" | docker login ghcr.io -u 你的用户名 --password-stdindocker push ghcr.io/your-username/your-image:latest docker image ls ghcr.io/your-username/your-image
方式3:多架构镜像构建(ARM/AMD) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 name: Build Multi-arch Docker Image jobs: build: runs-on: ubuntu-latest strategy: matrix: platform: - linux/amd64 - linux/arm64 - linux/arm/v7 steps: - uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to GHCR uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v5 with: context: . platforms: ${{ matrix.platform }} push: true tags: | ghcr.io/${{ github.repository }}:latest ghcr.io/${{ github.repository }}:${{ github.sha }}
三、完整实战示例:Unity 构建镜像 1. Dockerfile 示例:Unity 构建环境 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 FROM unityci/editor:ubuntu-2021.3 .21 f1-base-1.0 .1 AS builderRUN apt-get update && apt-get install -y \ git \ curl \ wget \ zip \ unzip \ python3 \ python3-pip \ && rm -rf /var/lib/apt/lists/* WORKDIR /workspace COPY BuildScripts/ ./BuildScripts/ COPY Assets/ ./Assets/ ENV UNITY_PROJECT_PATH=/workspaceENV OUTPUT_PATH=/outputFROM ubuntu:22.04 AS runtimeRUN apt-get update && apt-get install -y \ ca-certificates \ && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY --from=builder /output/ ./ab/ EXPOSE 8080 CMD ["python3" , "-m" , "http.server" , "8080" ]
2. GitHub Actions 工作流配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 name: Unity AB Pipeline with Docker on: push: branches: [main , develop ] paths: - 'Assets/**' - 'BuildScripts/**' - 'Dockerfile.unity-builder' - '.github/workflows/unity-ab-pipeline.yml' release: types: [published ] jobs: build-unity-ab: runs-on: ubuntu-latest outputs: ab_version: ${{ steps.version.outputs.version }} steps: - name: Checkout code uses: actions/checkout@v4 with: submodules: recursive - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build Unity AB Docker image run: | docker build \ -f Dockerfile.unity-builder \ -t unity-ab-builder:latest \ . - name: Run Unity AB build in container run: | docker run --rm \ -v $(pwd)/output:/output \ unity-ab-builder:latest \ python3 BuildScripts/build_ab.py \ --platform StandaloneWindows64 \ --type Full \ --version 1.0.${{ github.run_number }} - name: Generate version info id: version run: | echo "version=1.0.${{ github.run_number }}" >> $GITHUB_OUTPUT build-and-push-docker: needs: build-unity-ab runs-on: ubuntu-latest permissions: contents: read packages: write steps: - name: Checkout code uses: actions/checkout@v4 - name: Download AB artifacts uses: actions/download-artifact@v4 with: name: ab-output path: output/ - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to GHCR uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata id: meta uses: docker/metadata-action@v5 with: images: ghcr.io/${{ github.repository }} tags: | type=raw,value=${{ needs.build-unity-ab.outputs.ab_version }} type=raw,value=latest type=sha,prefix={{branch}}- - name: Build and push AB runtime image uses: docker/build-push-action@v5 with: context: . file: Dockerfile.runtime push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-args: | AB_VERSION=${{ needs.build-unity-ab.outputs.ab_version }} deploy-to-test: needs: build-and-push-docker runs-on: ubuntu-latest environment: test steps: - name: Deploy to test environment run: | echo "部署镜像到测试环境..." echo "镜像: ghcr.io/${{ github.repository }}:${{ needs.build-unity-ab.outputs.ab_version }}" # 这里可以是实际的部署命令,如: # kubectl set image deployment/my-game ab-server=ghcr.io/...
3. 多阶段构建优化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 FROM node:18 -alpine AS depsWORKDIR /app COPY package*.json ./ RUN npm ci --only=production FROM node:18 -alpine AS builderWORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . RUN npm run build FROM nginx:alpine AS runnerCOPY --from=builder /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 CMD ["nginx" , "-g" , "daemon off;" ]
四、GitHub Packages 与 GHCR 对比 功能对比表
特性
GitHub Container Registry (GHCR)
GitHub Packages (Docker)
Docker Hub
完全免费额度
500 MB + 1 GB/月
同 GHCR
有限免费(需订阅)
私有仓库
✅ 无限
✅ 无限
❌ 有限制
公共仓库
✅ 无限
✅ 无限
✅ 无限
与 GitHub 集成
✅ 深度集成
✅ 集成
❌ 有限
自动安全扫描
✅ 高级扫描
✅ 基础扫描
✅ 需付费
地理冗余
✅ 自动
✅ 自动
❌ 有限
访问控制
✅ 精细控制
✅ 精细控制
✅ 基础控制
Webhooks
✅ 支持
✅ 支持
✅ 支持
使用率统计
✅ 详细
✅ 详细
✅ 详细
迁移指南:从 Docker Hub 到 GHCR 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 docker pull username/image:tag docker tag username/image:tag ghcr.io/your-username/image:tag echo $GHCR_TOKEN | docker login ghcr.io -u your-username --password-stdindocker push ghcr.io/your-username/image:tag
五、访问控制与权限管理 1. 访问令牌类型
令牌类型
用途
权限范围
示例用途
GITHUB_TOKEN
Actions 自动认证
当前仓库
CI/CD 流水线
个人访问令牌
手动操作/脚本
可配置范围
本地推送镜像
部署密钥
只读访问
单个仓库
生产环境拉取
2. 权限配置示例 1 2 3 4 5 6 7 8 9 10 permissions: packages: write contents: read actions: read checks: write id-token: write
3. 组织级权限管理 1 2 3 4 5 6 7 8 9 10 11 12 13 权限结构: 组织 (your-org) ├── 包仓库 (ghcr.io/your-org/base-image) │ ├── 管理员: team-devops │ ├── 写入: team-backend │ └── 读取: team-frontend ├── 包仓库 (ghcr.io/your-org/web-app) │ ├── 管理员: team-frontend │ └── 读取: team-qa └── 包仓库 (ghcr.io/your-org/database) ├── 管理员: team-dba └── 读取: team-backend
六、镜像管理与维护 1. 标签策略最佳实践 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 tags: | # 语义化版本 type=semver,pattern={{version}} # v1.2.3 type=semver,pattern={{major}}.{{minor}} # v1.2 type=semver,pattern={{major}} # v1 type=ref,event=branch type=ref,event=tag type=sha,prefix=sha- type=raw,value=latest type=raw,value=nightly
2. 自动清理旧镜像 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 name: Cleanup Old Docker Images on: schedule: - cron: '0 3 * * 0' workflow_dispatch: jobs: cleanup: runs-on: ubuntu-latest permissions: packages: write contents: read steps: - name: Cleanup old images uses: snok/container-retention-policy@v2 with: image-names: | ghcr.io/${{ github.repository }}/* keep-at-least: 10 keep-tags: | ^latest$ # 保留 latest 标签 ^v[0-9]+\.[0-9]+\.[0-9]+$ # 保留正式版本 ^main$ # 保留 main 分支构建 cut-off: P30D dry-run: false
3. 镜像安全扫描 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 name: Security Scan Docker Images on: push: branches: [main ] tags: [v* ] jobs: scan: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Build Docker image run: docker build -t myapp:latest . - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: image-ref: 'myapp:latest' format: 'sarif' output: 'trivy-results.sarif' - name: Run Grype vulnerability scanner uses: anchore/scan-action@v3 with: image: myapp:latest fail-build: false - name: Upload SARIF results uses: github/codeql-action/upload-sarif@v2 with: sarif_file: trivy-results.sarif
七、高级使用场景 1. 跨仓库共享基础镜像 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 FROM ubuntu:22.04 RUN apt-get update && apt-get install -y \ python3 python3-pip nodejs npm FROM ghcr.io/org/base-image:latest AS builder WORKDIR /app COPY . . RUN npm install && npm run build FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html
2. 使用缓存加速构建 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - name: Set up Docker Buildx with cache uses: docker/setup-buildx-action@v3 with: driver-opts: | image=moby/buildkit:latest # 使用 GitHub Actions 缓存 cache-from=type=gha cache-to=type=gha,mode=max cache-from: | type=registry,ref=ghcr.io/${{ github.repository }}:buildcache cache-to: | type=registry,ref=ghcr.io/${{ github.repository }}:buildcache,mode=max
3. 多云部署策略 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 deploy: strategy: matrix: cloud: [aws , azure , gcp ] steps: - name: Authenticate to ${{ matrix.cloud }} uses: docker/login-action@v3 with: registry: ${{ matrix.cloud == 'aws' && 'public.ecr.aws' || matrix.cloud == 'azure' && 'azurecr.io' || matrix.cloud == 'gcp' && 'gcr.io' }} - name: Push to ${{ matrix.cloud }} run: | # 从 GHCR 拉取 docker pull ghcr.io/${{ github.repository }}:${{ env.VERSION }} docker tag ghcr.io/${{ github.repository }}:${{ env.VERSION }} \ ${{ matrix.cloud.registry }}/${{ github.repository }}:${{ env.VERSION }} docker push ${{ matrix.cloud.registry }}/${{ github.repository }}:${{ env.VERSION }}
八、成本优化策略 1. 镜像层优化技巧 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 FROM ubuntu:22.04 RUN apt-get update RUN apt-get install -y python3 RUN apt-get install -y nodejs RUN apt-get install -y git COPY package.json . RUN npm install FROM ubuntu:22.04 AS builderRUN apt-get update && \ apt-get install -y \ python3 \ nodejs \ git \ && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . FROM node:18 -alpine AS runner COPY --from=builder /app /app
2. 存储成本控制 1 2 3 4 5 6 7 8 9 10 docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" docker image prune -a --filter "until=24h" docker run --rm -it \ -v /var/run/docker.sock:/var/run/docker.sock \ wagoodman/dive:latest ghcr.io/your-org/image:latest
3. 传输成本优化 1 2 3 4 5 6 7 8 9 10 11 12 - name: Build with content-based tagging run: | # 构建时不指定标签 docker build -t myapp . DIGEST=$(docker inspect myapp --format='{{.Id}}') docker tag myapp ghcr.io/${{ github.repository }}@${DIGEST} docker push ghcr.io/${{ github.repository }}@${DIGEST}
九、故障排查与监控 1. 常见问题解决
问题
原因
解决方案
推送失败:denied
权限不足
检查 GITHUB_TOKEN 或 PAT 权限
镜像过大超限
超过免费额度
优化镜像大小,删除旧镜像
构建超时
网络问题或构建复杂
增加 timeout,使用镜像缓存
安全扫描失败
存在高危漏洞
更新基础镜像,修复漏洞
拉取缓慢
地理距离远
使用镜像加速器或 CDN
2. 监控指标 1 2 3 4 5 6 - name: Check package usage run: | curl -s -H "Authorization: token ${{ secrets.GH_TOKEN }}" \ https://api.github.com/users/${{ github.actor }}/packages?package_type=container \ | jq '.[] | {name: .name, version_count: .version_count}'
3. 日志与调试 1 2 3 4 5 6 7 8 9 10 11 docker build --progress=plain --no-cache -t myapp . gh run view --log $RUN_ID docker inspect ghcr.io/username/image:tag docker history ghcr.io/username/image:tag --no-trunc
十、完整实战工作流 企业级镜像流水线 graph TD
A[代码提交到 GitHub] --> B{GitHub Actions 触发}
B --> C[代码质量检查]
C --> D[构建 Docker 镜像]
D --> E[安全漏洞扫描]
E --> F{扫描通过?}
F -->|是| G[推送到 GHCR]
F -->|否| H[通知开发团队]
G --> I[部署到测试环境]
I --> J[自动化测试]
J --> K{测试通过?}
K -->|是| L[推送到生产环境]
K -->|否| M[回滚并通知]
L --> N[监控运行状态]
style A fill:#f9f,stroke:#333
style L fill:#9f9,stroke:#333
style H fill:#f99,stroke:#333
配置清单总结
必须文件 :
.github/workflows/docker.yml - CI/CD 配置
Dockerfile - 镜像构建定义
.dockerignore - 排除不必要的文件
推荐配置 :
docker-compose.yml - 本地开发环境
Makefile - 构建命令封装
scripts/ - 辅助脚本目录
安全配置 :
GitHub Secrets(存储敏感信息)
代码签名(可选)
访问控制策略
总结 GitHub Container Registry 的核心优势:
无缝集成 - 与 GitHub Actions、Packages 深度集成
成本效益 - 对开源项目和小团队完全免费
安全性 - 内置漏洞扫描和访问控制
易用性 - 使用熟悉的 GitHub 界面和 API
使用建议:
小型项目/初创公司 → 直接使用 GHCR
企业级应用 → GHCR + 自建镜像仓库混合
需要多云部署 → GHCR 作为主仓库,同步到各云
一句话总结: GitHub 不仅可以打镜像,而且提供了一套完整的、与代码仓库深度集成的容器镜像解决方案,特别适合 GitOps 和 DevOps 工作流。