目次
Docker Hub への push チュートリアル:イメージを公開・共有する方法
自分のコンピューターでビルドしたイメージをサーバーで実行したり、チームと共有したりするには、Registry に push します。最もよく使われるのは Docker Hub で、次に GitHub Container Registry(ghcr.io)や各クラウドプラットフォームの Registry が使われます。
イメージ名で push 先が決まる
push するとき、Docker はイメージ名に基づいて送信先の Registry とアカウントを決定します(命名規則はイメージを参照してください)。
| 名前 | push 先 |
|---|---|
yourname/mysite:1.0.0 | Docker Hub の yourname アカウント |
ghcr.io/yourname/mysite:1.0.0 | GitHub Container Registry |
localhost:5000/mysite:1.0.0 | ローカルの 5000 ポートで稼働するプライベート Registry |
そのため、push する前に docker tag を使って、イメージに送信先に対応した名前を付けます。
ログインせずに push するとどうなるか
まず、ログインせずに Docker Hub へ直接 push した場合の結果を見てみましょう。
$ docker tag nginx:1.30 yourname/mysite:1.0.0
$ docker push yourname/mysite:1.0.0
The push refers to repository [docker.io/yourname/mysite]
f4616bb1be1c: Unavailable
f1a6a629b824: Unavailable
3d774efa34e3: Unavailable
ecc510c1e359: Unavailable
push access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
push access denied ... authorization failed:ログインしておらず、yourname も自分のアカウント名ではないため、Docker Hub に拒否されました。以下でアカウント登録、ログイン、push の順に進めます。
Docker Hub に push する
1. アカウントを登録する
Docker の公式サイトでアカウントを登録します(メールアドレスを使うか、Google または GitHub アカウントで登録できます)。Username は、以降イメージ名の先頭に付ける名前空間です。

2. アクセストークンを作成してログインする
Docker Hub のアカウント設定で Personal Access Token を作成し、パスワードの代わりに使うことをおすすめします。権限を制限することもできます(たとえば、読み書きは許可し、削除は禁止するなど)。
docker login -u yourname
プロンプトに従ってアクセストークンを貼り付けます。ログインに成功すると Login Succeeded と表示されます。
3. リポジトリを作成する(任意)
初めて push すると、Docker Hub がリポジトリを自動で作成します。説明をあらかじめ設定したい場合や、プライベートにしたい場合は、Docker Hub のサイトで Create repository を選択します。

Docker Hub のリポジトリはデフォルトで公開されています。無料プランではプライベートリポジトリの数に制限があります。詳細は Docker Hub のプランを確認してください。
4. タグを付けて push する
docker build -t yourname/mysite:1.0.0 -t yourname/mysite:latest .
docker push yourname/mysite:1.0.0
docker push yourname/mysite:latest
-t は複数回使えるので、一度に複数の名前を付けられます。docker push --all-tags yourname/mysite を使って、すべてのタグを一度に push することもできます。push の出力形式は、後述する「プライベート Registry を自分で構築する」の実例と同じです。
push 後は、Docker Hub リポジトリの Tags タブで各タグと、他の人がダウンロードするためのコマンドを確認できます。

5. 別のマシンで使う
docker pull yourname/mysite:1.0.0
docker run -d -p 8080:80 yourname/mysite:1.0.0
プライベート Registry を自分で構築する:push と pull の実演
Docker 公式の registry イメージを使うと、プライベート Registry をすぐに構築できます。アカウントは不要なので、「push」を手軽に体験する方法としても最適です。
$ docker run -d -p 5000:5000 --restart unless-stopped -v registry-data:/var/lib/registry --name registry registry:3
Unable to find image 'registry:3' locally
3: Pulling from library/registry
e2de96513ba9: Already exists
90764beeca7f: Pull complete
8dc2188d2a74: Pull complete
783ed5b12fca: Pull complete
2aef3a8beb68: Pull complete
Digest: sha256:ddf754342cfc8acc51a56d5d0ab6af06826461864460636d8bd5c546dab2a7b8
Status: Downloaded newer image for registry:3
c5d02febbf0fd6d8c17e6818990adb28fd0a97c380a0d4c0a58ec793f685e4a0
タグを付けて push します。
$ docker tag nginx:1.30 localhost:5000/mysite:1.0.0
$ docker tag nginx:1.30 localhost:5000/mysite:latest
$ docker push localhost:5000/mysite:1.0.0
The push refers to repository [localhost:5000/mysite]
3d774efa34e3: Pushed
ecc510c1e359: Pushed
f4616bb1be1c: Pushed
f1a6a629b824: Pushed
cb44c3fe542b: Pushed
121907e00c1c: Pushed
220a6ac36368: Pushed
1.0.0: digest: sha256:6e2a172ae5503c0df64cd3294b57c86394ced402016a8cc45436086fa51f5d02 size: 2288
i Info → Not all multiplatform-content is present and only the available single-platform image was pushed
sha256:9bf97bd7714f5e24c1ccd545ecb9eb5435cb6d109c97cebb15e7e455e0239edb -> sha256:6e2a172ae5503c0df64cd3294b57c86394ced402016a8cc45436086fa51f5d02
$ docker push --all-tags localhost:5000/mysite
The push refers to repository [localhost:5000/mysite]
220a6ac36368: Layer already exists
3d774efa34e3: Layer already exists
ecc510c1e359: Layer already exists
f4616bb1be1c: Layer already exists
f1a6a629b824: Layer already exists
cb44c3fe542b: Layer already exists
121907e00c1c: Layer already exists
1.0.0: digest: sha256:6e2a172ae5503c0df64cd3294b57c86394ced402016a8cc45436086fa51f5d02 size: 2288
220a6ac36368: Layer already exists
3d774efa34e3: Layer already exists
ecc510c1e359: Layer already exists
f4616bb1be1c: Layer already exists
f1a6a629b824: Layer already exists
cb44c3fe542b: Layer already exists
121907e00c1c: Layer already exists
latest: digest: sha256:6e2a172ae5503c0df64cd3294b57c86394ced402016a8cc45436086fa51f5d02 size: 2288
i Info → Not all multiplatform-content is present and only the available single-platform image was pushed
sha256:9bf97bd7714f5e24c1ccd545ecb9eb5435cb6d109c97cebb15e7e455e0239edb -> sha256:6e2a172ae5503c0df64cd3294b57c86394ced402016a8cc45436086fa51f5d02
i Info → Not all multiplatform-content is present and only the available single-platform image was pushed
sha256:9bf97bd7714f5e24c1ccd545ecb9eb5435cb6d109c97cebb15e7e455e0239edb -> sha256:6e2a172ae5503c0df64cd3294b57c86394ced402016a8cc45436086fa51f5d02
- 初回の push では、各レイヤーに Pushed(アップロード済み)と表示されます。
--all-tagsでlatestを push すると、すべてのレイヤーに Layer already exists と表示されます。1.0.0とlatestは同じイメージで、Registry にこれらのレイヤーがすでにあるため、再アップロードは不要です。- 最後の
Infoは Docker 29 の通知です。ローカルにダウンロードした nginx はlinux/amd64プラットフォームのみなので、push されたのもこのプラットフォームだけです。マルチプラットフォームイメージの push 方法はマルチプラットフォームイメージを参照してください。
Registry の API で内容を確認します。
$ curl -s http://localhost:5000/v2/_catalog
{"repositories":["mysite"]}
$ curl -s http://localhost:5000/v2/mysite/tags/list
{"name":"mysite","tags":["1.0.0","latest"]}
ローカルのバージョンを削除してから、自分の Registry から再度ダウンロードします。
$ docker rmi localhost:5000/mysite:1.0.0 localhost:5000/mysite:latest
Untagged: localhost:5000/mysite:1.0.0
Untagged: localhost:5000/mysite:latest
$ docker pull localhost:5000/mysite:1.0.0
1.0.0: Pulling from mysite
Digest: sha256:6e2a172ae5503c0df64cd3294b57c86394ced402016a8cc45436086fa51f5d02
Status: Downloaded newer image for localhost:5000/mysite:1.0.0
localhost:5000/mysite:1.0.0
この方法で構築した Registry にはアカウント認証も HTTPS もありません。ローカルまたは内部ネットワークでのテストに限って使用してください。
localhostの Registry はそのまま使えますが、それ以外のアドレスにある HTTP Registry は Docker に拒否されるため、insecure-registriesの設定が別途必要です。本番環境では TLS と認証を設定するか、クラウドプラットフォームが提供する Registry(AWS ECR、Google Artifact Registry、Azure Container Registry など)を使ってください。
GitHub Container Registry(ghcr.io)に push する
コードを GitHub に置いているプロジェクトに適しています。まず GitHub で write:packages 権限を持つ Personal Access Token を作成し、次のコマンドを実行します。
echo $GITHUB_TOKEN | docker login ghcr.io -u 你的GitHub帳號 --password-stdin
docker tag mysite ghcr.io/你的帳號/mysite:1.0.0
docker push ghcr.io/你的帳號/mysite:1.0.0
--password-stdin は標準入力からパスワードを読み取るため、コマンド履歴にパスワードが残るのを防げます。
タグの命名方法
| 方法 | 例 | 説明 |
|---|---|---|
| セマンティックバージョニング | 1.4.2、1.4、1 | 複数の粒度のタグを同時に push し、利用者が更新範囲を選べるようにします |
| Git commit | sha-3f2a1c9 | 各イメージを正確なコードに対応させられます |
| 環境 | staging、production | デプロイ中のバージョンを指す可変タグです |
latest | latest | 試用には便利ですが、本番環境ではこれに依存しないでください |
本番環境にデプロイするときは、固定のバージョン番号を使ってください。サーバーで実行中のバージョンが分かり、前のバージョンにもすぐに戻せます(クラウドサーバーへのデプロイを参照してください)。
ログアウトと認証情報
docker logout
docker logout ghcr.io
ログイン情報はデフォルトで ~/.docker/config.json に保存されます。Docker Desktop は代わりに OS の認証情報マネージャー(Windows 資格情報マネージャー、macOS キーチェーン)に保存するため、より安全です。
まとめ
- イメージ名のプレフィックスで push 先の Registry が決まります。
- アカウントのパスワードではなく、アクセストークン(Access Token)でログインします。
docker tagで送信先の名前を付けてから、docker pushを実行します。- 本番環境では固定バージョンのタグを使い、
latestに依存しないでください。
練習問題
練習 1:この章の方法でローカル Registry(registry:3、5000 番ポート)を起動し、alpine:3.23 を push します。ローカルのコピーを削除してから、再度ダウンロードしてください。
解答
docker run -d -p 5000:5000 --name registry registry:3
docker tag alpine:3.23 localhost:5000/alpine:3.23
docker push localhost:5000/alpine:3.23
docker rmi localhost:5000/alpine:3.23
docker pull localhost:5000/alpine:3.23
よくある質問
push したときに denied: requested access to the resource is denied と表示されます。どうすればよいですか?
ログインしていないか、イメージ名のアカウント部分が自分のアカウント名ではない可能性があります。名前は 自分のアカウント名/リポジトリ:tag とし、先に docker login を実行してください。
Docker Hub のプライベートリポジトリは有料ですか?
無料アカウントでも限られた数のプライベートリポジトリを作成できます。数や制限については Docker Hub の公式プランを確認してください。GitHub Container Registry を使う方法もあります。
自動で push できますか?
GitHub Actions を使えば、コードを push したときやバージョンタグを付けたときに、自動でビルドして push できます。[GitHub Actions による自動ビルド](/ja/docker/ci-cd/)を参照してください。
更新日 2026年10月14日