6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHub Container Registry(ghcr)でコンテナイメージを管理する

Last updated at Posted at 2024-04-28

はじめに

この記事ではコンテナイメージをビルドし、GitHub Container Registry(以下、ghcr)にpushする手順を整理します。 コマンドラインを使う方法とGitHub Actionsを使う方法の2つを紹介します。

ghcrとは

GitHubが提供しているコンテナレジストリです。

他のコンテナレジストリの選択肢としてはAmazon ECR・Google Container Registry、Azure Container Registry等が挙げられます。 これらと比較してghcrは「GitHub Actionsとの連携が容易」「クラウドベンダーのリソースやトークンを管理する手間が不要」という優位点があります。

GitHubを使っているプロジェクトではコンテナレジストリとしてgchrが有力な候補になるでしょう。

① コマンドラインでコンテナイメージをpushする

  1. Personal Access Token(PAT)を発行する
  2. ghcrにログインする
  3. コンテナイメージをビルドする
  4. コンテナイメージをpushする

1. Personal Access Token(PAT)を発行する

ghcrはPersonal Access Token(以下PAT)による認証のみがサポートされています。
personal access token (classic) の作成手順
に沿ってトークンを発行します。

作成後にトークンの値を確認することはできないため、必ずトークンの値を控えてください

ghcrにコンテナイメージをpushするには「write:packages」権限を適用する必要があります。

GitHub_PAT.png

2. ghcrにログインする

コンテナイメージをghcrにpushするためには事前にghcrにログインする必要があります。
ログインには先ほど作成したPATを使います。

今回は~/.ghcr_token.txtにトークン文字列が書き込まれているという体で手順を実行します。

$ cat ~/.ghcr_token.txt | docker login ghcr.io -u USERNAME --password-stdin
Login Succeeded

Login Succeedと表示されれば成功です。

3. コンテナイメージをビルドする

今回はコンテナイメージをpushすることが目的なので、どんなイメージでも問題ありません。
ここでは適当にPythonのイメージを用意します。

.
|- app.py
|- Dockerfile
app.py
print("Hello, World!")
Dockerfile
FROM python:3.12-slim

COPY app.py .
CMD ["python", "./app.py"]
$ docker build -t python-test .
[+] Building 0.1s (7/7) FINISHED                                                                     docker:default
 => [internal] load build definition from Dockerfile                                                           0.0s
 => => transferring dockerfile: 102B                                                                           0.0s 
 => [internal] load .dockerignore                                                                              0.0s 
 => => transferring context: 48B                                                                               0.0s 
 => [internal] load metadata for docker.io/library/python:3.12-slim                                            0.0s 
 => [internal] load build context                                                                              0.0s 
 => => transferring context: 27B                                                                               0.0s 
 => [1/2] FROM docker.io/library/python:3.12-slim                                                              0.0s 
 => CACHED [2/2] COPY app.py .                                                                                 0.0s 
 => exporting to image                                                                                         0.0s 
 => => exporting layers                                                                                        0.0s 
 => => writing image sha256:7e21e1f0d2428688c81735807b66e5db23b2dc8121a3bebe48533078aee7b517                   0.0s 
 => => naming to docker.io/library/python-test                                                                 0.0s 

4. コンテナイメージをpushする

それでは先ほどビルドしたイメージをpushします。

ghcrにコンテナイメージをpushするためにはghcr.io/<USERNAME>/<IMAGENAME>:TAGの形式でタグ付けする必要があります。GitHubのユーザ名がjunpei-azumaでイメージ名がpython-test, タグ名を1.0としたい場合、以下のようになります。

また、CLIからイメージをpushする場合、リポジトリと紐づけることができないことに注意が必要です。1

$ docker tag python-test:latest ghcr.io/junpei-azuma/python-test:1.0.0

それではコンテナイメージをpushします。

$ docker push ghcr.io/junpei-azuma/python-test:1.0.0
The push refers to repository [ghcr.io/junpei-azuma/python-test]
2b6d15ba5b96: Pushed
6258d28909ff: Layer already exists
cfaf35e1cecf: Layer already exists
c6bc67c64ae2: Layer already exists
bfc9081d1eb2: Layer already exists
1f00ff201478: Layer already exists
1.0.0: digest: sha256:7ad574ae5599e33b8c100ebf5376ced4eae97b1bafe1e549751ea8168cec5651 size: 1577

pushしたバージョンのイメージが作成されていれば成功です。

image.png

② GitHub Actionsでコンテナイメージをpushする

  1. ghcrにログインする
  2. コンテナイメージをビルド・pushする

①と比較してこの方法には以下のメリットがあります。そのため、実運用ではGitHub Actionsを使う方法が一般的です。

  1. 毎回コマンドを手打ちする必要がない
  2. イメージをリポジトリと紐づけることができる
  3. データ転送に課金されない2

今回は「GitHubでタグを新しく作成するとコンテナイメージをビルド→pushする」という処理を行うワークフローを実装します。

build-image.yml
name: Build And Push Container Image

on:
  push:
    tags:
      - "*"

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: python-test
jobs:
  build-and-push:
    runs-on: ubuntu-latest
    # イメージをプッシュする権限をGITHUB_TOKENに付与する
    permissions:
      contents: read
      packages: write
    steps:
    - name: Checkout
      uses: actions/checkout@v4
    # 1. ghcrにログインする
    - name: Login to GitHub Container Registry
      uses: docker/login-action@v3
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}
    # 2. コンテナイメージをビルド・pushする
    - name: Build and Push Container
      uses: docker/build-push-action@v5
      with:
        push: true
        tags: ${{ env.REGISTRY }}/${{ github.repository }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }} 

1. ghcrにログインする

CLを使う場合と同じく最初にghcrにログインします。
自前でスクリプトを書いても良いのですが、今回はGitHub Market Placeで提供されているdocker-loginアクションを使います。

こちらのアクションはthird party製ではありますが、dockerが開発しているため公式製と同程度に信頼できると見てよいでしょう。

パラメータ

このアクションは下記のパラメータを受け取ります。

名前 デフォルト値 概要
registry String docker.io コンテナレジストリのアドレス。
username String コンテナレジストリのユーザ名
(今回の場合、GitHubのユーザ名)
password String コンテナレジストリの認証用パスワード・トークン
ecr String auto コンテナレジストリがECRかどうか
logout Bool true ジョブの終了後にコンテナレジストリからログアウトするかどうか

今回はregistry,username,passwordの3つを指定します。

  • registry: ghcr.io
  • username: ${{ github.actor }} (ワークフローの実行ユーザ) 3
  • password: ${{ secrets.GITHUB_TOKEN }}(ワークフローの起動時に生成される一意なトークン)

公式マニュアルの実装例はこちら

2. コンテナイメージをビルド・pushする

続いてコンテナイメージをビルド・pushします。ここでもGitHub Market Placeのbuild-push-actionアクションを使います。

パラメータ

数が多く、全部は書いていられないのでよく使われるものだけ記載します。

名前 概要
context String ビルドを実行するカレントディレクトリ. デフォルト値はリポジトリのルートパス
file String Dockerfileのパス. デフォルト値は{context}/Dockerfile
push Bool コンテナレジストリにpushするかどうか(デフォルト値はfalse)
tags List/CSV タグの値のリスト

今回はpushtagsを指定します。

  • push: コンテナレジストリにイメージをpushするのでtrue
  • tags: ghcr.io/<REPOSITRYNAME>/<USERNAME>/<IMAGENAME>:<TAGNAME> となるように指定

3. ワークフローを実行する

それではワークフローを実行します。
mainブランチにpushして適当にタグを打ちます。

push_tag.png

コンテナイメージが追加されました。

image.png

おわりに

今回はGitHub Container Registryにコンテナイメージをpushする方法をまとめました。
GitHub内でビルド~push~保存が完結するので運用しやすいと思いました。

参考資料

  1. GitHub Docs コンテナイメージをプッシュする

  2. GitHub Packages の課金について

  3. コンテキスト

6
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?