1. 简介
私有 Docker 镜像在访问受限仓库或注册中心中存储的镜像时需要用户进行身份验证。与任何人都可以访问的公有镜像不同,这些镜像仅对具有正确凭证(如用户名和密码、令牌或 API 密钥)的用户开放访问权限。
因此,在 GitHub Actions 工作流中使用私有 Docker 镜像时,必须在工作流中配置身份验证。本教程将介绍在 GitHub Actions 工作流中安全访问私有 Docker 注册中心的关键技术。所有命令均在 Ubuntu 20.04 上使用 Docker Engine 28.1.1 执行。
2. 前提条件
在 GitHub Actions 中实现私有 Docker 镜像访问之前,我们需要准备以下内容:
- 已启用 Actions 的 GitHub 仓库
- 可访问的私有 Docker 注册中心(本文使用 Docker Hub、GitHub Container Registry、AWS Elastic Container Registry 和 Google Artifact Registry)
- 具有适当权限的注册中心凭证
- 对 GitHub Actions 工作流语法有基本了解
接下来,我们创建一个示例镜像用于后续演示。定义一个使用 Alpine 基础镜像的 Dockerfile,运行时输出 Hello from Baeldung!
:
$ cat Dockerfile
FROM alpine:latest
CMD ["echo", "Hello from Baeldung!"]
构建镜像并命名为 hello-baeldung:1.0
:
$ docker build -f Dockerfile -t hello-baeldung:1.0 .
设置环境变量方便后续使用:
$ IMAGE=hello-baeldung
$ TAG=1.0
$ LOCAL_IMAGE=$IMAGE:$TAG
运行本地镜像确认输出:
$ docker run hello-baeldung:1.0
Hello from Baeldung!
输出如预期所示。
3. 使用 GitHub Container Registry (GHCR)
GitHub Container Registry(GHCR)是 GitHub 提供的托管 Docker 镜像注册服务,允许在 GitHub 生态系统中无缝存储、管理和分发 Docker 镜像。
GHCR 的镜像地址格式如下:
ghcr.io/USERNAME/IMAGE:TAG
ghcr.io/ORGANIZATION/IMAGE:TAG
3.1. 生成个人访问令牌(PAT)
要将镜像推送到 GHCR,需使用 GitHub 个人访问令牌(PAT)进行身份验证。
前往 GitHub 仪表盘,创建一个具有 write:packages
和 delete:packages
权限的 PAT:
将令牌保存为环境变量并登录 GHCR:
$ GHCR_PAT=<personal_access_token>
$ echo "$GHCR_PAT" | docker login ghcr.io -u <GITHUB_USERNAME> --password-stdin
3.2. 推送镜像
设置 GHCR 仓库地址并推送镜像:
$ GHCR_REPO=ghcr.io/$GHCR_USER/$IMAGE
$ docker tag $LOCAL_IMAGE $GHCR_REPO:$TAG
$ docker push $GHCR_REPO:$TAG
镜像将被安全地存储在 GHCR 中。
3.3. 在 GitHub Actions 中使用私有 GHCR 镜像
创建工作流文件 .github/workflows/ghcr-private-images.yaml
:
on:
push:
branches:
- main
jobs:
run-ghcr-image:
runs-on: ubuntu-latest
steps:
- name: Login to GitHub Container Registry
run: echo "${{ secrets.TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Pull and Run Image
run: |
docker pull ghcr.io/${{ secrets.OWNER }}/${{ secrets.IMAGE }}:${{ secrets.TAG }}
docker run ghcr.io/${{ secrets.OWNER }}/${{ secrets.IMAGE }}:${{ secrets.TAG }}
在 GitHub 仓库中配置以下 secrets:
TOKEN
: GitHub PATOWNER
: 用户名或组织名IMAGE
: 镜像名(如hello-baeldung
)TAG
: 镜像标签(如1.0
)
提交工作流后,在 Actions 页面查看执行结果:
✅ 输出为 Hello from Baeldung!
,说明镜像拉取和运行成功。
4. 使用 Docker Hub
Docker Hub 是 Docker 提供的官方镜像注册服务,用于共享和存储容器镜像。
4.1. 创建 PAT
在 Docker Hub 仪表盘创建一个具有读写权限的 PAT:
保存凭证并登录:
$ DOCKERHUB_TOKEN=<dockerhub_pat_token>
$ DOCKERHUB_USER=<dockerhub_username>
$ echo "$DOCKERHUB_TOKEN" | docker login -u "$DOCKERHUB_USER" --password-stdin
4.2. 推送镜像
设置仓库地址并推送:
$ DOCKERHUB_REPO=$DOCKERHUB_USER/$IMAGE
$ docker tag $LOCAL_IMAGE $DOCKERHUB_REPO:$TAG
$ docker push $DOCKERHUB_REPO:$TAG
将仓库设为私有:
4.3. 在 GitHub Actions 中使用私有 Docker Hub 镜像
创建工作流文件 .github/workflows/dockerhub-private-image.yaml
:
name: Run Private DockerHub Image
on:
push:
branches:
- main
jobs:
run-dockerhub-image:
runs-on: ubuntu-latest
steps:
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Pull and Run Image
run: |
docker pull ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.IMAGE }}:${{ secrets.TAG }}
docker run ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.IMAGE }}:${{ secrets.TAG }}
在 GitHub 设置以下 secrets:
DOCKERHUB_USERNAME
DOCKERHUB_TOKEN
提交后查看执行结果:
✅ 成功输出 Hello from Baeldung!
5. 使用 AWS Elastic Container Registry (ECR)
AWS ECR 是 Amazon 提供的托管 Docker 注册中心,支持安全存储和管理 Docker 镜像。
5.1. 账号配置
设置 AWS 区域和账户 ID:
$ AWS_REGION=<aws_region>
$ AWS_ACCOUNT_ID=<account_id>
登录 ECR:
$ aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com
5.2. 推送镜像
创建仓库并推送:
$ aws ecr describe-repositories --repository-names "$IMAGE" --region $AWS_REGION >/dev/null 2>&1 || \
aws ecr create-repository --repository-name "$IMAGE" --region $AWS_REGION
$ ECR_REPO=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$IMAGE
$ docker tag $LOCAL_IMAGE $ECR_REPO:$TAG
$ docker push $ECR_REPO:$TAG
5.3. 创建 IAM 用户
创建 IAM 用户并为其分配访问 ECR 的权限:
$ aws iam create-user --user-name github-ecr-user
$ aws iam create-access-key --user-name github-ecr-user
创建并绑定策略:
$ aws iam create-policy --policy-name ECRReadOnlyAccess --policy-document file://ecr-policy.json
$ aws iam attach-user-policy --user-name github-ecr-user --policy-arn arn:aws:iam::<ACCOUNT_ID>:policy/ECRReadOnlyAccess
5.4. 在 GitHub Actions 中使用私有 ECR 镜像
创建工作流文件 .github/workflows/aws-ecr-private-images.yaml
:
name: Run Private AWS ECR Image
on:
push:
branches:
- main
jobs:
run-ecr-image:
runs-on: ubuntu-latest
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Pull and Run Image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ secrets.ECR_REPOSITORY }}
IMAGE_TAG: ${{ secrets.TAG }}
run: |
docker pull $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker run $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
在 GitHub 设置以下 secrets:
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_REGION
ECR_REPOSITORY
提交后查看执行结果:
✅ 成功输出 Hello from Baeldung!
6. 使用 Google Artifact Registry
Google Artifact Registry 是 Google Cloud 提供的包管理与容器镜像注册服务。
6.1. 项目配置与认证
配置 Docker 与 gcloud:
$ gcloud auth configure-docker
6.2. 推送镜像
设置项目 ID 和仓库地址:
$ PROJECT_ID=$(gcloud config get-value project)
$ GCR_REPO=gcr.io/$PROJECT_ID/$IMAGE
$ docker tag $LOCAL_IMAGE $GCR_REPO:$TAG
$ docker push $GCR_REPO:$TAG
6.3. 创建服务账号密钥
创建服务账号并授权:
$ gcloud iam service-accounts create github-gcr-user
$ gcloud projects add-iam-policy-binding $PROJECT_ID --member="serviceAccount:github-gcr-user@$PROJECT_ID.iam.gserviceaccount.com" --role="roles/storage.objectViewer"
$ gcloud projects add-iam-policy-binding $PROJECT_ID --member="serviceAccount:github-gcr-user@$PROJECT_ID.iam.gserviceaccount.com" --role="roles/artifactregistry.reader"
生成密钥并编码:
$ gcloud iam service-accounts keys create key.json --iam-account=github-gcr-user@$PROJECT_ID.iam.gserviceaccount.com
$ base64 -w 0 key.json > key.b64
6.4. 在 GitHub Actions 中使用私有 GCR 镜像
创建工作流文件 .github/workflows/gcr-private-image.yaml
:
name: Run Private GCR Image
on:
push:
branches:
- main
jobs:
run-gcr-image:
runs-on: ubuntu-latest
steps:
- id: 'auth'
uses: 'google-github-actions/auth@v1'
with:
credentials_json: '${{ secrets.GCP_CREDENTIALS }}'
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v1
- name: Configure Docker for GCR
run: |
gcloud auth configure-docker
- name: Pull and Run Image
env:
GCR_REGISTRY: gcr.io
GCP_PROJECT: ${{ secrets.GCP_PROJECT_ID }}
IMAGE_NAME: ${{ secrets.IMAGE }}
IMAGE_TAG: ${{ secrets.TAG }}
run: |
docker pull $GCR_REGISTRY/$GCP_PROJECT/$IMAGE_NAME:$IMAGE_TAG
docker run $GCR_REGISTRY/$GCP_PROJECT/$IMAGE_NAME:$IMAGE_TAG
在 GitHub 设置以下 secrets:
GCP_PROJECT_ID
GCP_CREDENTIALS
(base64 编码的密钥)
提交后查看执行结果:
✅ 成功输出 Hello from Baeldung!
7. 总结
本文介绍了如何在 GitHub Actions 中安全地使用来自以下注册中心的私有 Docker 镜像:
- GitHub Container Registry
- Docker Hub
- AWS Elastic Container Registry
- Google Artifact Registry
我们通过使用 IAM、服务账号、PAT 和仓库 secrets 实现了安全认证,确保了工作流的安全性和可维护性。这些方法是目前 CI/CD 中推荐的最佳实践。