Docker設定 · 5 min read · Oct 05, 2025
Ubuntu 22.04でプライベートDockerレジストリを設定する方法

組織で働いていて、Dockerイメージを社内で保持して迅速にデプロイしたい場合、プライベートDockerリポジトリをホストすることが最適です。プライベートDockerレジストリを持つことで、イメージ配信パイプラインを所有し、イメージのストレージと配信をより厳密に管理できます。CI/CDシステムとレジストリを統合することで、ワークフローを改善できます。
このチュートリアルでは、Amazon S3をストレージ場所として使用して、Ubuntu 22.04サーバーでプライベートDockerレジストリを設定し、使用する方法を学びます。
前提条件
- Ubuntu 22.04を搭載した2台のLinuxサーバー。一方のサーバーはレジストリホストとして機能し、もう一方はリクエストを送信し、ホストからイメージを受信するためのクライアントとして使用されます。
- ホストサーバーを指す登録済みのドメイン名。チュートリアルでは
registry.example.comを使用します。 - 両方のマシンでsudo権限を持つ非rootユーザー。
- すべてが更新されていることを確認します。
$ sudo apt update $ sudo apt upgrade - システムに必要な数個のパッケージ。
$ sudo apt install wget curl nano software-properties-common dirmngr apt-transport-https gnupg2 ca-certificates lsb-release ubuntu-keyring unzip -yこれらのパッケージのいくつかは、すでにシステムにインストールされている場合があります。
ステップ1 - ファイアウォールの設定
最初のステップはファイアウォールを設定することです。Ubuntuにはデフォルトでufw(Uncomplicated Firewall)が付属しています。
ファイアウォールが実行中かどうかを確認します。
$ sudo ufw status
次の出力が得られるはずです。
Status: inactive
SSHポートを許可して、ファイアウォールを有効にしたときに現在の接続が切断されないようにします。
$ sudo ufw allow OpenSSH
HTTPおよびHTTPSポートも許可します。
$ sudo ufw allow http
$ sudo ufw allow https
ファイアウォールを有効にします。
$ sudo ufw enable
コマンドは既存のssh接続を中断する可能性があります。操作を続行しますか (y|n)? y
ファイアウォールはアクティブで、システム起動時に有効になります
再度ファイアウォールの状態を確認します。
$ sudo ufw status
似たような出力が表示されるはずです。
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
80/tcp ALLOW Anywhere
443 ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)
443 (v6) ALLOW Anywhere (v6)
ステップ2 - DockerおよびDocker Composeのインストール
このステップは、サーバーとクライアントマシンの両方で必要です。
Ubuntu 22.04には古いバージョンのDockerが付属しています。最新バージョンをインストールするには、まずDocker GPGキーをインポートします。
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
Dockerリポジトリファイルを作成します。
$ echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
システムのリポジトリリストを更新します。
$ sudo apt update
最新バージョンのDockerをインストールします。
$ sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
実行中であることを確認します。
$ sudo systemctl status docker
? docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2023-04-13 09:37:09 UTC; 3min 47s ago
TriggeredBy: ? docker.socket
Docs: https://docs.docker.com
Main PID: 2106 (dockerd)
Tasks: 7
Memory: 26.0M
CPU: 267ms
CGroup: /system.slice/docker.service
??2106 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
デフォルトでは、Dockerはroot権限を必要とします。dockerコマンドを実行するたびにsudoを使用しないようにするには、ユーザー名をdockerグループに追加します。
$ sudo usermod -aG docker $(whoami)
この変更を有効にするには、サーバーからログアウトして同じユーザーで再度ログインする必要があります。または、次のコマンドを使用します。
$ su - ${USER}
ユーザーがDockerグループに追加されたことを確認します。
$ groups
navjot wheel docker
ステップ3 - Dockerレジストリの設定
ユーザーディレクトリの作成
レジストリ設定用のディレクトリを作成します。
$ mkdir ~/docker-registry
docker-registryディレクトリに移動します。
$ cd ~/docker-registry
HTTP認証パスワード、Nginx設定ファイル、SSL証明書を保存するためのディレクトリを作成します。
$ mkdir auth
Nginxログを保存するための別のディレクトリを作成します。
$ mkdir logs
Amazon S3バケットの作成
レジストリデータとイメージをサーバーに保存するか、クラウドホスティングサービスを使用できます。チュートリアルでは、Amazon S3クラウドサービスを使用します。
次のステップは、いくつかの重要な設定を含む設定ファイルを設定することです。これらの設定はdocker-compose.ymlファイルにも定義できますが、別のファイルを持つ方がはるかに良いです。
次の設定でバケットを作成します。
- ACLは無効にする必要があります。
- バケットへのパブリックアクセスは無効にする必要があります。
- バケットバージョニングは無効にする必要があります。
- Amazon S3管理キーを使用してバケット暗号化を有効にします。(SSE-S3)
- オブジェクトロックは無効にする必要があります。
次のポリシーを持つIAMユーザーを作成します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:ListBucketMultipartUploads"
],
"Resource": "arn:aws:s3:::S3_BUCKET_NAME"
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:ListMultipartUploadParts",
"s3:AbortMultipartUpload"
],
"Resource": "arn:aws:s3:::S3_BUCKET_NAME/*"
}
]
}
S3_BUCKET_NAMEをあなたのS3バケットの名前に置き換えます。
後で使用するために、バケットのシークレットキー、シークレット値、およびバケットリージョンをメモしておきます。
Docker Composeファイルの作成
docker-compose.ymlファイルを作成し、編集のために開きます。
$ nano docker-compose.yml
次のコードを貼り付けます。
services:
registry:
image: registry:2
restart: always
environment:
- REGISTRY_STORAGE=s3
- REGISTRY_STORAGE_S3_REGION=us-west-2
- REGISTRY_STORAGE_S3_BUCKET=hf-docker-registry
- REGISTRY_STORAGE_S3_ENCRYPT=true
- REGISTRY_STORAGE_S3_CHUNKSIZE=5242880
- REGISTRY_STORAGE_S3_SECURE=true
- REGISTRY_STORAGE_S3_ACCESSKEY=AKIA3FIG4NVFNXKQXMSJ
- REGISTRY_STORAGE_S3_SECRETKEY=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
- REGISTRY_STORAGE_S3_V4AUTH=true
- REGISTRY_STORAGE_S3_ROOTDIRECTORY=/image-registry
- REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR=inmemory
- REGISTRY_HEALTH_STORAGEDRIVER_ENABLED=false
nginx:
image: "nginx:alpine"
ports:
- 443:443
links:
- registry:registry
volumes:
- ./auth:/etc/nginx/conf.d
- ./auth/nginx.conf:/etc/nginx/nginx.conf:ro
- ./logs:/var/log/nginx
- /etc/letsencrypt:/etc/letsencrypt
ファイルを保存するには、Ctrl + Xを押し、プロンプトが表示されたらYを入力します。
私たちがコンポーズファイルで設定した内容を見ていきましょう。
- 最初のステップは、ハブからDockerレジストリのバージョン2の最新イメージを取得することです。最新のタグは使用していません。なぜなら、メジャーバージョンのアップグレードの場合に問題を引き起こす可能性があるからです。これを2に設定すると、すべての2.xアップデートを取得しながら、次のメジャーバージョンに自動的にアップグレードされるのを防ぐことができます。これにより、破壊的な変更が導入される可能性があります。
- レジストリコンテナは、失敗や予期しないシャットダウンの場合に常に再起動するように設定されています。
- Amazon S3ストレージ用のさまざまな環境変数を設定しました。これらを簡単に見ていきましょう。 - REGISTRY_STORAGEはストレージの種類を設定します。Amazon S3を使用しているため、s3を選択しました。
- REGISTRY_STORAGE_S3_REGIONはS3バケットのリージョンを設定します。
- REGISTRY_STORAGE_S3_BUCKETはS3バケットの名前を設定します。
- REGISTRY_STORAGE_S3_ENCRYPT - バケット暗号化を有効にした場合はtrueに設定します。
- REGISTRY_STORAGE_S3_CHUNKSIZEはアップロードチャンクのサイズを設定します。5MB(5 1024 1024)より大きくする必要があります。
- REGISTRY_STORAGE_S3_SECURE - HTTPSを使用する場合はtrueに設定します。
- REGISTRY_STORAGE_S3_ACCESSKEYおよびREGISTRY_STORAGE_S3_SECRETKEY - IAMユーザーを作成した後に取得したユーザー資格情報です。
- REGISTRY_STORAGE_S3_V4AUTH - AWS認証のv4を使用する場合はtrueに設定します。S3ログインに関するエラーが発生している場合はfalseに設定します。
- REGISTRY_STORAGE_S3_ROOTDIRECTORY - レジストリデータが保存されるバケット内のルートディレクトリを設定します。
- REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR - キャッシュの場所を設定します。この場合、メモリに保存しています。Redisを使用するように設定することもできます。
- REGISTRY_HEALTH_STORAGEDRIVER_ENABLED - レジストリのストレージヘルスチェックサービスを無効にするにはfalseに設定します。これをfalseに設定しないと、レジストリにバグがあり、問題が発生する可能性があります。
- Dockerレジストリはポート5000を介して通信します。これがサーバーでDockerに公開されているポートです。
./auth:/etc/nginx/conf.dのマッピングにより、すべてのNginxの設定がコンテナ内で利用可能になります。./auth/nginx.conf:/etc/nginx/nginx.conf:roは、システムからコンテナ内の設定ファイルに読み取り専用モードでマッピングします。./logs:/var/log/nginxは、コンテナ内のNginxログディレクトリにマッピングすることで、システム上でNginxのログにアクセスできるようにします。- Dockerレジストリの設定は、コンテナ内の
/etc/docker/registry/config.ymlファイルに保存されており、次のステップで作成する現在のディレクトリ内のconfig.ymlファイルにマッピングされています。
認証の設定
HTTP認証を設定するには、httpd-toolsパッケージをインストールする必要があります。
$ sudo apt install apache2-utils -y
~/docker-registry/authディレクトリにパスワードファイルを作成します。
$ htpasswd -Bc ~/docker-registry/auth/nginx.htpasswd user1
New password:
Re-type new password:
Adding password for user user1
-cフラグは新しいファイルを作成するようにコマンドに指示し、-BフラグはDockerがサポートするbcryptアルゴリズムを使用します。user1を任意のユーザー名に置き換えます。
さらにユーザーを追加したい場合は、再度コマンドを実行しますが、-cフラグは使用しません。
$ htpasswd -B ~/docker-registry/auth/registry.password user2
これで、ファイルは認証のためにレジストリコンテナにマッピングされます。
ステップ4 - SSLのインストール
SSL証明書を生成するためにCertbotをインストールする必要があります。Ubuntuのリポジトリを使用してCertbotをインストールするか、Snapdツールを使用して最新バージョンを取得できます。Snapdバージョンを使用します。
Ubuntu 22.04にはデフォルトでSnapdがインストールされています。次のコマンドを実行して、Snapdのバージョンが最新であることを確認します。
$ sudo snap install core && sudo snap refresh core
Certbotをインストールします。
$ sudo snap install --classic certbot
次のコマンドを使用して、Certbotコマンドが/usr/binディレクトリで実行できるようにシンボリックリンクを作成します。
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
次のコマンドを実行してSSL証明書を生成します。
$ sudo certbot certonly --standalone --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d registry.example.com
上記のコマンドは、サーバーの/etc/letsencrypt/live/registry.example.comディレクトリに証明書をダウンロードします。
Diffie-Hellmanグループ証明書を生成します。
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
Certbotの更新スケジューラーサービスを確認します。
$ sudo systemctl list-timers
snap.certbot.renew.serviceが実行されるようにスケジュールされたサービスの1つとして表示されます。
NEXT LEFT LAST PASSED UNIT ACTIVATES
.....
Sun 2023-04-14 00:00:00 UTC 19min left Sat 2023-02-25 18:04:05 UTC n/a snap.certbot.renew.timer snap.certbot.renew.service
Sun 2023-04-14 00:00:20 UTC 19min left Sat 2023-02-25 10:49:23 UTC 14h ago apt-daily-upgrade.timer apt-daily-upgrade.service
Sun 2023-04-14 00:44:06 UTC 3h 22min left Sat 2023-02-25 20:58:06 UTC 7h ago apt-daily.timer apt-daily.service
SSL更新が正常に機能しているかどうかを確認するために、プロセスのドライランを実行します。
$ sudo certbot renew --dry-run
エラーが表示されなければ、すべて設定完了です。証明書は自動的に更新されます。
Dhparamファイルをコンテナにコピー
Diffie-Hellmanグループ証明書を~/docker-registry/authディレクトリにコピーします。これはコンテナにマッピングされます。
$ sudo cp /etc/ssl/certs/dhparam.pem ~/docker-registry/auth
ステップ5 - Nginxの設定
次のステップは、DockerレジストリサーバーのフロントエンドプロキシとしてNginxサーバーを設定することです。Dockerレジストリにはポート5000で動作する組み込みサーバーがあります。これをNginxの背後に置きます。
~/docker-registry/auth/nginx.confファイルを作成して編集します。
$ sudo nano ~/docker-registry/auth/nginx.conf
次のコードを貼り付けます。
events {
worker_connections 1024;
}
http {
upstream docker-registry {
server registry:5000;
}
## 変数を設定して、
## 'Docker-Distribution-Api-Version'ヘッダーを追加する必要があるかどうかを判断します。
## レジストリは常にこのヘッダーを設定します。
## Nginxがプロキシする前に認証を行う場合、ヘッダーは未設定になります。
map $upstream_http_docker_distribution_api_version $docker_distribution_api_version {
'' 'registry/2.0';
}
server {
listen 443 ssl http2;
server_name registry.example.com;
# SSL
ssl_certificate /etc/letsencrypt/live/registry.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/registry.example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/registry.example.com/chain.pem;
access_log /var/log/nginx/registry.access.log;
error_log /var/log/nginx/registry.error.log;
# https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.htmlからの推奨事項
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1;
ssl_session_cache shared:SSL:10m;
ssl_dhparam /etc/nginx/conf.d/dhparam.pem;
resolver 8.8.8.8;
# 大きなイメージのアップロードを避けるために制限を無効にします
client_max_body_size 0;
# HTTP 411を避けるために必要です: Issue #1486 (https://github.com/moby/moby/issues/1486)
chunked_transfer_encoding on;
location /v2/ {
# docker 1.5以前からの接続を許可しない
# docker pre-1.6.0はping時にユーザーエージェントを正しく設定しなかったため、「Go *」ユーザーエージェントをキャッチします
if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
return 404;
}
# v2に基本認証を追加するにはauth_basic設定を使用します。
auth_basic "Registry realm";
auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd;
## $docker_distribution_api_versionが空である場合、ヘッダーは追加されません。
## この変数が定義されている上記のmapディレクティブを参照してください。
add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;
proxy_pass http://docker-registry;
proxy_set_header Host $http_host; # dockerクライアントのために必要
proxy_set_header X-Real-IP $remote_addr; # 実際のクライアントのIPを渡す
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 900;
}
}
}
ファイルを保存するには、Ctrl + Xを押し、プロンプトが表示されたらYを入力します。
ステップ6 - Dockerレジストリを起動する
Dockerレジストリのディレクトリに移動します。
$ cd ~/docker-registry
Dockerコンテナを起動します。
$ docker compose up -d
コンテナの状態を確認します。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3328b7e36bb2 nginx:alpine "/docker-entrypoint.…" About a minute ago Up 3 seconds 80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp docker-registry-nginx-1
bf7cdfc0e013 registry:2 "/entrypoint.sh /etc…" About a minute ago Up About a minute 5000/tcp docker-registry-registry-1
Dockerレジストリにログインします。
$ docker login -u=user1 -p=password https://registry.example.com
次の出力が得られます。
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /home/username/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
ブラウザでhttps://registry.example.com/v2/のURLを開くこともでき、ユーザー名とパスワードを求められます。{}の空のページが表示されるはずです。
ターミナルでURLを確認するには、curlを使用します。
$ curl -u user1 -X GET https://registry.example.com/v2/
Enter host password for user 'user1':
{}
最新のUbuntu Dockerイメージをダウンロードします。
$ docker pull ubuntu:latest
このイメージにプライベートレジストリ用のタグを付けます。
$ docker tag ubuntu:latest registry.example.com/ubuntu2204
イメージをレジストリにプッシュします。
$ docker push registry.example.com/ubuntu2204
プッシュが成功したかどうかをテストします。
$ curl -u user1 -X GET https://registry.example.com/v2/_catalog
Enter host password for user 'user1':
{"repositories":["ubuntu2204"]}
プロンプトが表示されたらNginx認証パスワードを入力すると、レジストリを介して利用可能なリポジトリのリストが表示されます。
ターミナルを使用してログアウトして資格情報をクリアします。
$ docker logout https://registry.example.com
Removing login credentials for registry.example.com
現在使用可能なDockerイメージのリストを確認します。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry 2 8db46f9d7550 2 weeks ago 24.2MB
nginx alpine 8e75cbc5b25c 2 weeks ago 41MB
ubuntu latest 08d22c0ceb15 5 weeks ago 77.8MB
registry.example.com/ubuntu2204 latest 08d22c0ceb15 5 weeks ago 77.8MB
ステップ7 - クライアントマシンからDockerレジストリにアクセスして使用する
クライアントサーバーにログインします。ステップ1では、クライアントマシンにDockerをインストールしました。
クライアントマシンからプライベートDockerレジストリにログインします。
$ docker login -u=user1 -p=password https://registry.example.com
レジストリからUbuntuイメージをプルします。
$ docker pull registry.example.com/ubuntu2204
クライアントマシン上のすべてのイメージをリストします。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.example.com/ubuntu2204 latest 08d22c0ceb15 5 weeks ago 77.8MB
ダウンロードしたイメージを使用してコンテナを作成して起動します。
$ docker run -it registry.example.com/ubuntu2204 /bin/bash
Ubuntuコンテナ内のシェルにログインします。
root@647899f255db:
Linuxバージョンを確認するために次のコマンドを実行します。
root@a2da49fdbea9$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.2 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.2 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
これで、クライアントマシンからDockerレジストリを使用できるようになります。
結論
これで、Amazon S3をストレージとして使用するUbuntu 22.04サーバーにプライベートDockerレジストリを設定する方法に関するチュートリアルが終了します。質問がある場合は、下のコメントに投稿してください。
新しい投稿を受信箱で受け取る
スパムはありません。いつでも購読を解除できます。