# コンテナレジストリの利用

Docker イメージと OCI イメージは、 Container registryに格納および管理できます。

## Container registry について

Container registry は、Organization または個人アカウント内にコンテナー イメージを格納し、イメージをリポジトリに関連付けることができます。 権限をリポジトリから継承するか、リポジトリとは別に細かい権限を設定するかを選ぶことができます。 パブリック コンテナー イメージに匿名でアクセスすることもできます。

## Container registryサポートについて

Container registryは現在、次のコンテナー イメージ形式をサポートしています。

* [Docker Image Manifest V2、Schema 2](https://docs.docker.com/registry/spec/manifest-v2-2/)
* [Open Container Initiative (OCI) 仕様](https://github.com/opencontainers/image-spec)

Docker イメージをインストールまたは発行する場合、Container registryでは、Windows イメージなどの外部レイヤーがサポートされます。

## Container registry への認証

> \[!NOTE]
> GitHub Packages では、 personal access token (classic)を使用した認証のみがサポートされます。 詳しくは、「[個人用アクセス トークンを管理する](/ja/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)」をご覧ください。

非公開パッケージ、内部パッケージ、公開パッケージを発行、インストール、削除するには、アクセス トークンが必要です。

personal access token (classic)、あるいは GitHub Packages API で認証を受けるのに、GitHub を利用できます。 personal access token (classic) を作成するときは、必要に応じてさまざまなスコープをトークンに割り当てることができます。 personal access token (classic) のパッケージ関連のスコープについては、「[GitHub Packagesの権限について](/ja/packages/learn-github-packages/about-permissions-for-github-packages#about-scopes-and-permissions-for-package-registries)」を参照してください。

GitHub Packagesワークフロー内でGitHub Actionsレジストリに認証を受けるには、以下の方法が使えます。

* `GITHUB_TOKEN` では、ワークフロー リポジトリに関連付けられているパッケージを発行します。
* 他のプライベート リポジトリに関連付けられたパッケージをインストールするために、少なくとも `read:packages` スコープが設定された personal access token (classic) (リポジトリにパッケージへの読み取りアクセス権が付与されている場合は、`GITHUB_TOKEN` を使用できます)。 「[パッケージのアクセス制御と可視性の設定](/ja/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility)」を参照してください)。

### GitHub Actions ワークフローでの認証

このレジストリでは、詳細なアクセス許可がサポートされています。 詳細なアクセス許可をサポートするレジストリの場合、 GitHub Actions ワークフローがレジストリに対する認証に personal access token を使用している場合は、 `GITHUB_TOKEN`を使用するようにワークフローを更新することを強くお勧めします。
personal access tokenを使用してレジストリに対して認証を行うワークフローの更新に関するガイダンスについては、[GitHub Actionsでのパッケージの公開とインストール](/ja/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions#upgrading-a-workflow-that-accesses-a-registry-using-a-personal-access-token) を参照してください。

> \[!NOTE]
> REST API を使ってパッケージを削除および復元する GitHub Actions ワークフローの機能は、現在 パブリック プレビュー 段階であり、変更される可能性があります。

トークンにパッケージへのアクセス許可が`GITHUB_TOKEN`されている場合は、GitHub Actions ワークフローの`admin`を使用して、REST API を使用してパッケージを削除または復元できます。 ワークフローを使ってパッケージを発行するリポジトリと、パッケージに明示的に接続したリポジトリには、リポジトリ内のパッケージに対する `admin` アクセス許可が自動的に付与されます。

`GITHUB_TOKEN` の詳細については、「[ワークフローでの認証に GITHUB\_TOKEN を使用する](/ja/actions/tutorials/authenticate-with-github_token#using-the-github_token-in-a-workflow)」を参照してください。 アクションでレジストリを使うときのベスト プラクティスについて詳しくは、「[危険にさらされたランナー](/ja/actions/concepts/security/compromised-runners#cross-repository-access)」をご覧ください。

また、パッケージに対するアクセス許可を個別に付与することも選択できますGitHub Codespaces とGitHub Actions。 詳細については、「[パッケージのアクセス制御と可視性の設定](/ja/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility#ensuring-github-codespaces-access-to-your-package)」および「[パッケージのアクセス制御と可視性の設定](/ja/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility#ensuring-workflow-access-to-your-package)」を参照してください。

### personal access token (classic)を使用した認証の実行

> \[!NOTE]
> GitHub Packages では、 personal access token (classic)を使用した認証のみがサポートされます。 詳しくは、「[個人用アクセス トークンを管理する](/ja/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)」をご覧ください。

1. 実行するタスクに適したスコープを持つ新しい personal access token (classic) を作成します。 OrganizationがSSOを必須としている場合は、新しいトークンでSSOを有効化しなければなりません。

   > \[!NOTE]
   > 既定では、ユーザー インターフェイスで`write:packages`のpersonal access token (classic) スコープを選択すると、`repo`スコープも選択されます。
   > `repo`スコープでは不要で広範なアクセスが提供されるため、特にGitHub Actionsワークフローには使用しないことをお勧めします。 詳しくは、「[危険にさらされたランナー](/ja/actions/concepts/security/compromised-runners#cross-repository-access)」をご覧ください。 回避策として、次の URL を使用して、ユーザー インターフェイスで `write:packages` の personal access token (classic) スコープのみを選択できます: `https://github.com/settings/tokens/new?scopes=write:packages`。

   * `read:packages` スコープを選択すると、コンテナー イメージがダウンロードされ、そのメタデータが読み取られます。
   * `write:packages` スコープを選択すると、コンテナー イメージがダウンロードされ、アップロードされ、そのメタデータが読み書きされます。
   * `delete:packages` スコープを選択すると、コンテナー イメージが削除されます。

   詳しくは、「[個人用アクセス トークンを管理する](/ja/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)」をご覧ください。

2. personal access token (classic)を保存します。 トークンは環境変数として保存することをおすすめします。

   ```shell
   export CR_PAT=YOUR_TOKEN
   ```

3. 使用しているコンテナーの種類に対応する CLI を使用して、Container registry の `ghcr.io` サービスにサインインします。

   ```shell
   $ echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin
   > Login Succeeded
   ```

## コンテナイメージをプッシュする

この例では、最新バージョンの `IMAGE_NAME` をプッシュします。

```shell
docker push ghcr.io/NAMESPACE/IMAGE_NAME:latest
```

`NAMESPACE` を、イメージのスコープ指定先にしたい個人アカウントまたは組織の名前に置き換えます。

以下の例では、イメージのバージョン `2.5` をプッシュします。

```shell
docker push ghcr.io/NAMESPACE/IMAGE_NAME:2.5
```

パッケージを最初に公開する際のデフォルトの可視性はプライベートです。 可視性の変更やアクセス許可の設定については、「[パッケージのアクセス制御と可視性の設定](/ja/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility)」を参照してください。 ユーザー インターフェイスまたはコマンド ラインを使用して、発行済みパッケージをリポジトリにリンクできます。 詳しくは、「[リポジトリのパッケージへの接続](/ja/packages/learn-github-packages/connecting-a-repository-to-a-package)」をご覧ください。

コマンド ラインからコンテナー イメージをプッシュすると、そのイメージは既定ではリポジトリにリンクされません。 これは、`ghcr.io/octocat/my-repo:latest` のように、リポジトリの名前に一致する名前空間でイメージにタグした場合でも当てはまります。

リポジトリをコンテナー パッケージに接続する最も簡単に方法は、`${{secrets.GITHUB_TOKEN}}` を利用してワークフローからパッケージを発行することです。ワークフローが含まれるリポジトリが自動的にリンクされるためです。 同じ名前空間に以前、パッケージをプッシュしているが、そのパッケージをリポジトリに接続していない場合、パッケージをプッシュする許可は `GITHUB_TOKEN` に与えられません。

コマンド ラインからイメージを発行するときにリポジトリを接続し、GitHub Actions ワークフローの使用時に適切なアクセス許可を `GITHUB_TOKEN` に確実に与えるため、ラベル `org.opencontainers.image.source` を `Dockerfile` に追加することをお勧めします。 詳しくは、この記事の「[コンテナー イメージのラベル付け](#labelling-container-images)」と「[GitHub Actionsでのパッケージの公開とインストール](/ja/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions)」をご覧ください。

## コンテナイメージをプルする

### ダイジェストによるプル

常に同一のイメージを使用するため、`digest` SHA 値でプルするコンテナー イメージのバージョンを指定できます。

1. `docker inspect` または `docker pull` を使用してダイジェスト SHA 値を調べ、その SHA 値を `Digest:` の後にコピーします

   ```shell
   docker inspect ghcr.io/NAMESPACE/IMAGE_NAME
   ```

`NAMESPACE` を、イメージのスコープ指定先にする個人アカウントまたは Organization の名前に置き換えます。

1. 必要に応じてローカルでイメージを削除します。

   ```shell
   docker rmi ghcr.io/NAMESPACE/IMAGE_NAME:latest
   ```

2. イメージ名の後に `@YOUR_SHA_VALUE` を付けてコンテナー イメージをプルします。

   ```shell
   docker pull ghcr.io/NAMESPACE/IMAGE_NAME@sha256:82jf9a84u29hiasldj289498uhois8498hjs29hkuhs
   ```

### 名前で検索

```shell
docker pull ghcr.io/NAMESPACE/IMAGE_NAME
```

`NAMESPACE` を、イメージのスコープ指定先にする個人アカウントまたは Organization の名前に置き換えます。

### 名前とバージョンによるプル

名前と `1.14.1` バージョン タグにより Docker CLI でイメージをプルする例を以下に示します。

```shell
$ docker pull ghcr.io/NAMESPACE/IMAGE_NAME:1.14.1
> 5e35bd43cf78: Pull complete
> 0c48c2209aab: Pull complete
> fd45dd1aad5a: Pull complete
> db6eb50c2d36: Pull complete
> Digest: sha256:ae3b135f133155b3824d8b1f62959ff8a72e9cf9e884d88db7895d8544010d8e
> Status: Downloaded newer image for ghcr.io/NAMESPACE/IMAGE_NAME/release:1.14.1
> ghcr.io/NAMESPACE/IMAGE_NAME/release:1.14.1
```

`NAMESPACE` を、イメージのスコープ指定先にする個人アカウントまたは Organization の名前に置き換えます。

### 名前と最新バージョンによるプル

```shell
$ docker pull ghcr.io/NAMESPACE/IMAGE_NAME:latest
> latest: Pulling from NAMESPACE/IMAGE_NAME
> Digest: sha256:b3d3e366b55f9a54599220198b3db5da8f53592acbbb7dc7e4e9878762fc5344
> Status: Downloaded newer image for ghcr.io/NAMESPACE/IMAGE_NAME:latest
> ghcr.io/NAMESPACE/IMAGE_NAME:latest
```

`NAMESPACE` を、イメージのスコープ指定先にする個人アカウントまたは Organization の名前に置き換えます。

## コンテナイメージを構築する

以下の例では `hello_docker` イメージを構築します。

```shell
docker build -t hello_docker .
```

## コンテナイメージにタグ付けする

1. タグ付けする Docker イメージの ID を調べます。

   ```shell
   $ docker images
   > REPOSITORY                                            TAG                 IMAGE ID            CREATED             SIZE
   > ghcr.io/my-org/hello_docker         latest            38f737a91f39        47 hours ago        91.7MB
   > hello-world                                           latest              fce289e99eb9        16 months ago       1.84kB
   ```

2. イメージ ID を使用して、Docker イメージを任意のイメージ名とホスティング先でタグ付けします。

   ```shell
   docker tag 38f737a91f39 ghcr.io/NAMESPACE/NEW_IMAGE_NAME:latest
   ```

`NAMESPACE` を、イメージのスコープ指定先にしたい個人アカウントまたは組織の名前に置き換えます。

## コンテナー イメージのラベル付け

定義済みの注釈キーを使って、説明、ライセンス、ソース リポジトリなどのメタデータをコンテナー イメージに追加できます。 サポートされているキーの値は、イメージのパッケージ ページに表示されます。

ほとんどのイメージでは、Docker ラベルを使用して注釈キーをイメージに追加できます。 詳細については、Docker の公式ドキュメントの[LABEL](https://docs.docker.com/engine/reference/builder/#label)、およびリポジトリ内の[Pre-Defined Annotation Keys](https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys)を参照してください。

マルチアーキテクチャ イメージの場合は、イメージのマニフェストの `annotations` フィールドに適切な注釈キーを追加することで、イメージに説明を追加できます。 詳細については、「[マルチアーキテクチャ イメージへの説明の追加](#adding-a-description-to-multi-arch-images)」を参照してください。

Container registryでは、次の注釈キーがサポートされています。

| キー                                     | 説明                                                                                                                                                                                                       |
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `org.opencontainers.image.source`      | パッケージに関連付けられているリポジトリの URL。 詳しくは、「[リポジトリのパッケージへの接続](/ja/packages/learn-github-packages/connecting-a-repository-to-a-package#connecting-a-repository-to-a-container-image-using-the-command-line)」をご覧ください。 |
| `org.opencontainers.image.description` | 512 文字に制限されたテキストのみの説明。 この説明は、パッケージ ページのパッケージの名前の下に表示されます。                                                                                                                                                |
| `org.opencontainers.image.licenses`    | 256 文字に制限された SPDX ライセンス識別子 ("MIT" など)。 ライセンスは、パッケージ ページの \[詳細] サイドバーに表示されます。 詳細については、「[SPDX ライセンス一覧](https://spdx.org/licenses/)」を参照してください。                                                              |

Docker ラベルとしてキーを追加するには、`LABEL` の `Dockerfile` 命令を使用することをお勧めします。 たとえば、ユーザー `octocat` が `my-repo` を所有していて、MIT ライセンスの条件に従ってイメージが配布されている場合は、次の行を `Dockerfile` に追加します。

```dockerfile
LABEL org.opencontainers.image.source=https://github.com/octocat/my-repo
LABEL org.opencontainers.image.description="My container image"
LABEL org.opencontainers.image.licenses=MIT
```

> \[!NOTE]
> リポジトリにリンクされているパッケージを公開した場合、organization でアクセス許可の自動継承が無効にされていない限り、パッケージはリンクされたリポジトリのアクセス許可を自動的に継承し、リンクされたリポジトリ内の GitHub Actions ワークフローは自動的にパッケージにアクセスできるようになります。 詳しくは、「[パッケージのアクセス制御と可視性の設定](/ja/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility#about-inheritance-of-access-permissions)」をご覧ください。

または、`docker build` コマンドを使用して、ビルド時にラベルをイメージに追加することもできます。

```shell
$ docker build \
 --label "org.opencontainers.image.source=https://github.com/octocat/my-repo" \
 --label "org.opencontainers.image.description=My container image" \
 --label "org.opencontainers.image.licenses=MIT"
```

### マルチアーキテクチャ イメージへの説明の追加

マルチアーキテクチャ イメージは、複数のアーキテクチャをサポートするイメージです。 これは、1 つのマニフェスト内で、それぞれ異なるアーキテクチャをサポートするイメージの一覧を参照することによって機能します。

マルチアーキテクチャ イメージのパッケージ ページに表示される説明は、イメージのマニフェストの `annotations` フィールドから取得されます。 Docker ラベルと同様に、注釈によってメタデータをイメージに関連付ける方法が提供され、定義済みの注釈キーがサポートされます。 詳細については、[Annotations](https://github.com/opencontainers/image-spec/blob/main/annotations.md) が `opencontainers/image-spec` リポジトリ内に記載されているので参照してください。

マルチアーキテクチャ イメージの説明を指定するには、次のように、マニフェストの `org.opencontainers.image.description` フィールドで `annotations` キーの値を設定します。

```json
"annotations": {
  "org.opencontainers.image.description": "My multi-arch image"
}
```

たとえば、次の GitHub Actions ワークフロー ステップは、マルチアーチ イメージをビルドしてプッシュします。
`outputs` パラメーターを使用すると、イメージの説明が設定されます。

```yaml
# このワークフローはGitHubによって認定されていないアクションを使用します。
# それらはサードパーティによって提供され、
# 別個の利用規約、プライバシーポリシー、
# ドキュメントを参照してください。

- name: Build and push Docker image
  uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
  with:
    context: .
    file: ./Dockerfile
    platforms: ${{ matrix.platforms }}
    push: true
    outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=My multi-arch image
```

## トラブルシューティング

* Container registryには、レイヤーごとに 10 GB のサイズ制限があります。
* Container registryには、アップロードのタイムアウト制限が 10 分です。