任意のファイルをOCI RegistryにPushしてみる
目次
OCI レジストリはコンテナのイメージを保存するのに使うことが多いですが、コンテナイメージ以外のデータを保存することも可能です。
バイナリファイルなどビルドの成果物管理に OCI レジストリが使えると便利そうだなと思ったのでその検証をしてみました。
oras というプロジェクトがまさにそれを行っています。
oras で ghcr.io にファイルを push するワークフローを GitHub Actions で動かす
以下のような workflow を定義します。
oras-project/setup-oras@v1
で oras コマンドを利用できるようにします。oras login
ghcr.io にログインします。- 成果物として日付を output.txt に書き込みます
oras push
で ghcr.io に output.txt を push します。- タグには commit hash を使います
1name: Build binary push to github registry using oras
2on:
3 push:
4 branches:
5 - main
6
7jobs:
8 build-and-push:
9 runs-on: ubuntu-latest
10 permissions:
11 packages: write
12 steps:
13 - uses: actions/checkout@v4
14 - uses: oras-project/setup-oras@v1
15 - run: echo -n $GITHUB_TOKEN | oras login -u ${{ github.actor }} --password-stdin ghcr.io
16 env:
17 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
18 - run: date > output.txt
19 - run: oras push ghcr.io/ophum/kakisute/oras-test:${{ github.sha }} output.txt
以下のように実行できました。
Packages のページでも確認できます。
oras コマンドでファイルを pull する
public なパッケージの場合(oras)
public なパッケージだと認証なしで pull できます。
タグを確認 (oras public)
1hum@ryzen5pc:~/oras-test$ oras repo tags ghcr.io/ophum/kakisute/oras-test
23ed88f2e9ee119b0694e8cededcd7d1485e92649
3b4b9d43949141020a5a6a1205fd8047e1ff8f06d
458072af430466fddc68e557e38eea8ca4716c5f6
pull する (oras public)
1hum@ryzen5pc:~/oras-test$ ls
2hum@ryzen5pc:~/oras-test$ oras pull ghcr.io/ophum/kakisute/oras-test:b4b9d43949141020a5a6a1205fd8047e1ff8f06d
3✓ Pulled output.txt 29/29 B 100.00% 484µs
4 └─ sha256:2caee7636353b06e490e048bf0ff323347aaa7b59a4fa2a87f51e46687d3e2ee
5✓ Pulled application/vnd.oci.image.manifest.v1+json 589/589 B 100.00% 137µs
6 └─ sha256:6519123c64ebe8ab9b3e0593556b3786db9375e5bfbefe07155eb43d884f8dc0
7Pulled [registry] ghcr.io/ophum/kakisute/oras-test:b4b9d43949141020a5a6a1205fd8047e1ff8f06d
8Digest: sha256:6519123c64ebe8ab9b3e0593556b3786db9375e5bfbefe07155eb43d884f8dc0
output.txt
が存在することと書き込まれた内容を確認します。
1hum@ryzen5pc:~/oras-test$ ls
2output.txt
3hum@ryzen5pc:~/oras-test$ cat output.txt
4Sun Jun 29 05:29:16 UTC 2025
private なパッケージの場合 (oras)
oras login
oras login するか-u, -p オプションで認証情報を指定します。
gh コマンドのトークンを利用してみます。
1hum@ryzen5pc:~/oras-test$ gh auth login -h github.com -p https --scopes read:packages --web
2
3! First copy your one-time code: 156D-89E5
4Press Enter to open github.com in your browser...
5✓ Authentication complete.
6- gh config set -h github.com git_protocol https
7✓ Configured git protocol
8! Authentication credentials saved in plain text
9✓ Logged in as ophum
10hum@ryzen5pc:~/oras-test$ gh auth token | oras login -u ophum --password-stdin ghcr.io
11Login Succeeded
pull する(oras private)
1hum@ryzen5pc:~/oras-test$ oras pull ghcr.io/ophum/kakisute/oras-test:b4b9d43949141020a5a6a1205fd8047e1ff8f06d
2✓ Pulled output.txt 29/29 B 100.00% 667µs
3 └─ sha256:2caee7636353b06e490e048bf0ff323347aaa7b59a4fa2a87f51e46687d3e2ee
4✓ Pulled application/vnd.oci.image.manifest.v1+json 589/589 B 100.00% 0s
5 └─ sha256:6519123c64ebe8ab9b3e0593556b3786db9375e5bfbefe07155eb43d884f8dc0
6Pulled [registry] ghcr.io/ophum/kakisute/oras-test:b4b9d43949141020a5a6a1205fd8047e1ff8f06d
7Digest: sha256:6519123c64ebe8ab9b3e0593556b3786db9375e5bfbefe07155eb43d884f8dc0
1hum@ryzen5pc:~/oras-test$ cat output.txt
2Sun Jun 29 05:29:16 UTC 2025
curl でファイルを pull する
public なパッケージの場合 (curl)
トークンを作成 (curl public)
1hum@ryzen5pc:~/oras-test$ curl -so "token.json" "https://ghcr.io/token?service=ghcr.io&scope=repository:ophum/kakisute/oras-test:pull"
タグを確認 (curl public)
作成したトークンを Authorization ヘッダーに入れて実行します。
1hum@ryzen5pc:~/oras-test$ curl -s -H "Authorization: Bearer $(cat token.json | jq -r .token)" https:
2//ghcr.io/v2/ophum/kakisute/oras-test/tags/list | jq
3{
4 "name": "ophum/kakisute/oras-test",
5 "tags": [
6 "3ed88f2e9ee119b0694e8cededcd7d1485e92649",
7 "b4b9d43949141020a5a6a1205fd8047e1ff8f06d",
8 "58072af430466fddc68e557e38eea8ca4716c5f6"
9 ]
10}
マニフェストを確認 (curl public)
1hum@ryzen5pc:~/oras-test$ curl -so manifest.json \
2 -H "Accept: application/vnd.oci.image.manifest.v1+json" \
3 -H "Authorization: Bearer $(cat token.json | jq -r .token)" \
4 https://ghcr.io/v2/ophum/kakisute/oras-test/manifests/3ed88f2e9ee119b0694e8cededcd7d1485e92649
5hum@ryzen5pc:~/oras-test$ cat manifest.json | jq
6{
7 "schemaVersion": 2,
8 "mediaType": "application/vnd.oci.image.manifest.v1+json",
9 "artifactType": "application/vnd.unknown.artifact.v1",
10 "config": {
11 "mediaType": "application/vnd.oci.empty.v1+json",
12 "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
13 "size": 2,
14 "data": "e30="
15 },
16 "layers": [
17 {
18 "mediaType": "application/vnd.oci.image.layer.v1.tar",
19 "digest": "sha256:9378c2a8b36f97d973b728a0d944356874903b71c83fcdb68724ef3c19a687a1",
20 "size": 29,
21 "annotations": {
22 "org.opencontainers.image.title": "output.txt"
23 }
24 }
25 ],
26 "annotations": {
27 "org.opencontainers.image.created": "2025-06-29T05:28:08Z"
28 }
29}
output.txt をダウンロードする (curl public)
.layers[0].digest を指定してダウンロードします。
1hum@ryzen5pc:~/oras-test$ curl -L -s \
2 -H "Authorization: Bearer $(cat token.json | jq -r .token)" \
3 "https://ghcr.io/v2/ophum/kakisute/oras-test/blobs/$(cat manifest.json | jq -r '.layers[0].digest')"
4Sun Jun 29 05:28:08 UTC 2025
private なパッケージの場合
トークンを作成 (curl private)
public の時と同じ URL に Basic 認証付きで実行します。
1hum@ryzen5pc:~/oras-test$ curl -so "token.json" -u ophum:$(gh auth token) "https://ghcr.io/token?service=ghcr.io&scope=repository:ophum/kakisute/oras-test:pull"
タグを確認 (curl private)
あとは public の時と同じです。 作成したトークンを Authorization ヘッダーに入れて実行します。
1hum@ryzen5pc:~/oras-test$ curl -s -H "Authorization: Bearer $(cat token.json | jq -r .token)" https://ghcr.io/v2/ophum/kakisute/oras-test/tags/list | jq
2{
3 "name": "ophum/kakisute/oras-test",
4 "tags": [
5 "3ed88f2e9ee119b0694e8cededcd7d1485e92649",
6 "b4b9d43949141020a5a6a1205fd8047e1ff8f06d",
7 "58072af430466fddc68e557e38eea8ca4716c5f6"
8 ]
9}
マニフェストを確認 (curl private)
1hum@ryzen5pc:~/oras-test$ curl -so manifest.json \
2 -H "Accept: application/vnd.oci.image.manifest.v1+json" \
3 -H "Authorization: Bearer $(cat token.json | jq -r .token)" \
4 https://ghcr.io/v2/ophum/kakisute/oras-test/manifests/3ed88f2e9ee119b0694e8cededcd7d1485e92649
5hum@ryzen5pc:~/oras-test$ cat manifest.json | jq
6{
7 "schemaVersion": 2,
8 "mediaType": "application/vnd.oci.image.manifest.v1+json",
9 "artifactType": "application/vnd.unknown.artifact.v1",
10 "config": {
11 "mediaType": "application/vnd.oci.empty.v1+json",
12 "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
13 "size": 2,
14 "data": "e30="
15 },
16 "layers": [
17 {
18 "mediaType": "application/vnd.oci.image.layer.v1.tar",
19 "digest": "sha256:9378c2a8b36f97d973b728a0d944356874903b71c83fcdb68724ef3c19a687a1",
20 "size": 29,
21 "annotations": {
22 "org.opencontainers.image.title": "output.txt"
23 }
24 }
25 ],
26 "annotations": {
27 "org.opencontainers.image.created": "2025-06-29T05:28:08Z"
28 }
29}
output.txt をダウンロードする (curl private)
.layers[0].digest を指定してダウンロードします。
1hum@ryzen5pc:~/oras-test$ curl -L -s \
2 -H "Authorization: Bearer $(cat token.json | jq -r .token)" \
3 "https://ghcr.io/v2/ophum/kakisute/oras-test/blobs/$(cat manifest.json | jq -r '.layers[0].digest')"
4Sun Jun 29 05:28:08 UTC 2025