本文介绍一下如何使用 GitHub Actions 构建 Docker 镜像,并上传到 GitHub Packages。
GitHub Actions
GitHub Actions 是 GitHub 官方提供的一项自动化平台服务,主要用于自动化软件开发流程中的各类任务,尤其适合实现 CI/CD(持续集成与持续交付)。
详情可参考这一篇
GitHub Packages
GitHub Packages 是 GitHub 提供的一项软件包托管与管理服务,支持开发者将各种类型的软件包(如依赖库、容器镜像等)与源代码一同集中管理。通过这一平台,开发者可以在 GitHub 上安全地发布、安装和管理自己的包,无论是公开还是私有项目都能适用。
支持多种主流包管理器,包括 npm、Maven、NuGet、Docker、RubyGems、Gradle 等。
GitHub Packages 对于开源项目完全免费,对私有仓库也有免费额度。
手动上传镜像
基础用法和 Docker Hub 一样,但是域名为 ghcr.io
。
- 创建一个 Personal Access Token, https://github.com/settings/tokens/new?scopes=write:packages
- 勾选
write:packages
权限
如果是在 GitHub Actions 中访问 GitHub Packages,可以使用 GITHUB_TOKEN 。
一旦获取了 Token 就可以来使用登录访问镜像仓库。
export CR_PAT=YOUR_TOKEN
echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin
然后可以根据如下的命令来推送镜像。
docker build -t your-tag .
docker tag hello:latest ghcr.io/einverne/hello:latest
docker push ghcr.io/einverne/hello:latest
然后就可以在 GitHub 页面上看到。
自动构建并上传镜像
上面提到过 GitHub Actions 是 GitHub 推出的 CICD,既然都已经使用 GitHub Packages,那么直接使用 Actions 更方便。
name: Build Docker Image
# 当 push 到 master 分支,或者创建以 v 开头的 tag 时触发,可根据需求修改
on:
push:
branches:
- master
tags:
- v*
env:
REGISTRY: ghcr.io
IMAGE: einverne/hello
jobs:
build-and-push:
runs-on: ubuntu-latest
# 这里用于定义 GITHUB_TOKEN 的权限
permissions:
packages: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v2
# 缓存 Docker 镜像以加速构建
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: $-buildx-$
restore-keys: |
$-buildx-
# 配置 QEMU 和 buildx 用于多架构镜像的构建
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
- name: Inspect builder
run: |
echo "Name: $"
echo "Endpoint: $"
echo "Status: $"
echo "Flags: $"
echo "Platforms: $"
# 登录到 GitHub Packages 容器仓库
# secrets.GITHUB_TOKEN 不需要手动添加,直接就可以用
- name: Log in to the Container registry
uses: docker/login-action@v1
with:
registry: $
username: $
password: $
# 根据输入自动生成 tag 和 label 等数据,说明见下
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v3
with:
images: $/$
# 构建并上传
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
target: production
builder: $
platforms: linux/amd64,linux/arm64
push: true
tags: $
labels: $
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Inspect image
run: |
docker buildx imagetools inspect \
$/$:$