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を入力します。

私たちがコンポーズファイルで設定した内容を見ていきましょう。

  1. 最初のステップは、ハブからDockerレジストリのバージョン2の最新イメージを取得することです。最新のタグは使用していません。なぜなら、メジャーバージョンのアップグレードの場合に問題を引き起こす可能性があるからです。これを2に設定すると、すべての2.xアップデートを取得しながら、次のメジャーバージョンに自動的にアップグレードされるのを防ぐことができます。これにより、破壊的な変更が導入される可能性があります。
  2. レジストリコンテナは、失敗や予期しないシャットダウンの場合に常に再起動するように設定されています。
  3. 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に設定しないと、レジストリにバグがあり、問題が発生する可能性があります。
  1. Dockerレジストリはポート5000を介して通信します。これがサーバーでDockerに公開されているポートです。
  2. ./auth:/etc/nginx/conf.dのマッピングにより、すべてのNginxの設定がコンテナ内で利用可能になります。
  3. ./auth/nginx.conf:/etc/nginx/nginx.conf:roは、システムからコンテナ内の設定ファイルに読み取り専用モードでマッピングします。
  4. ./logs:/var/log/nginxは、コンテナ内のNginxログディレクトリにマッピングすることで、システム上でNginxのログにアクセスできるようにします。
  5. 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レジストリを設定する方法に関するチュートリアルが終了します。質問がある場合は、下のコメントに投稿してください。

Share: X/Twitter LinkedIn

新しい投稿を受信箱で受け取る

スパムはありません。いつでも購読を解除できます。