CI/CDでビルドしたDockerイメージを,どこに置いてVPSに配るか── これを解決するのがDockerレジストリだ.公開サービスもあるが,VPSに自前のプライベートレジストリを立てる選択肢を知っておくと,運用の自由度が大きく上がる.
自前レジストリがあれば,プライベートなイメージを自分の管理下で配布でき,外部サービスの制限やコストにも縛られない.CI/CDでビルドしたイメージをpushし,本番VPSがpullする── という現代的なデプロイの要になる.
この記事は,CI/CDでイメージを配布したい個人開発者・小規模チームに向けている.registryコンテナの構築から,HTTPS・認証・CI連携・イメージの掃除までを実践的に解説する.
読み終えたとき,あなたは自前のイメージ配布基盤を持ち,ビルドしたイメージを安全にpush/pullできるようになっている.
なぜ自前レジストリを立てるのか
Dockerイメージの配布には,イメージを保管するレジストリが要る.公開のレジストリサービスもあるが,プライベートなイメージの保管・転送量・容量・速度に制約やコストがかかることがある.
自前レジストリなら,自分のVPS内で完結する.CI/CDでビルドしたイメージを自前レジストリにpushし,本番VPSが同じネットワーク/近い場所からpullすれば,速くて制限のないデプロイができる.
またプライベートなコードを含むイメージを,自分の管理下に置ける安心感もある.外部サービスにイメージを預けたくない場合の選択肢になる.
ただし自前で運用する責任(HTTPS・認証・バックアップ・掃除)も負う.この記事ではそれらを安全に組む方法を示す.
レジストリの全体像 ― push と pull
Dockerレジストリは,イメージを保管し,push(アップロード)とpull(ダウンロード)を受け付けるサーバーだ.Docker公式のregistryイメージを使えば,VPS上に簡単に立てられる.
典型的なフローは,(1)CI/CDでイメージをビルド (2)自前レジストリにpush (3)本番VPSがpullしてデプロイだ.これにより「ビルド」と「実行」の場所を分離できる(イメージ最適化・CI/CDの記事も参照).
registryコンテナを立てる ― 最小構成
まずは基本のregistryコンテナを起動する.データ(イメージ)はvolumeに永続化するのを忘れずに(さもないとコンテナ再作成でイメージが消える).
registryの最小起動(compose)
services:
registry:
image: registry:2
restart: always
volumes:
- registrydata:/var/lib/registry # イメージを永続化
# 直接公開せず,後段でNginxにHTTPS終端させる
ports:
- "127.0.0.1:5000:5000"
volumes:
registrydata:ポイントはレジストリ自体は127.0.0.1:5000でlocalhostバインドし,外部に直接晒さないことだ.次のステップで,前段のNginxにHTTPS終端と認証を担わせる.イメージデータはregistrydata volumeに永続化する.
HTTPSと認証 ― 公開レジストリを安全にする
Dockerはデフォルトで,HTTPSでないレジストリへのpush/pullを拒否する(insecure registryの例外設定はあるが非推奨).そのため,前段のNginxでHTTPS終端し,さらにBasic認証で保護する.
Nginxで前段にHTTPS+Basic認証
# Basic認証ファイルを作成(htpasswd)
# htpasswd -Bc /etc/nginx/registry.htpasswd myuser
server {
listen 443 ssl;
server_name registry.example.com;
# ... Let's Encryptの証明書 ...
client_max_body_size 0; # 大きなイメージpushのため
location / {
auth_basic "Registry";
auth_basic_user_file /etc/nginx/registry.htpasswd;
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
}
}client_max_body_size 0は重要だ.イメージは大きいため,これを設定しないと大きなレイヤーのpushが413エラーで失敗する.Basic認証+HTTPSにより,認証した人だけが安全にpush/pullできる(SSL記事・リバースプロキシ記事も参照).
push と pull ― ログインして使う
レジストリができたら,docker loginで認証し,イメージにレジストリのホスト名を付けてpush/pullする.
ログイン・push・pull
# 認証
docker login registry.example.com
# イメージにレジストリ名をタグ付けしてpush
docker tag myapi registry.example.com/myapi:1.0
docker push registry.example.com/myapi:1.0
# 本番VPSでpull
docker pull registry.example.com/myapi:1.0イメージ名の頭にレジストリのホスト名を付けるのがポイントだ(registry.example.com/myapi:1.0).これでDockerはどのレジストリにpush/pullするかを判断する.本番のcomposeでは,このフルネームでイメージを指定すれば,自前レジストリからpullしてデプロイできる.
CI/CD連携 ― ビルドしてpushを自動化
真価が出るのがCI/CDとの連携だ.GitHub Actions等でイメージをビルドし,自前レジストリにpush,本番VPSがpullする(CI/CDの記事も参照).
CIでビルド→自前レジストリへpush(概念)
# CI(GitHub Actions等)の中で
# 認証情報はSecretsから
docker login registry.example.com -u $REG_USER -p $REG_PASS
docker build -t registry.example.com/myapi:$GITHUB_SHA .
docker push registry.example.com/myapi:$GITHUB_SHA
# 本番VPSでは pull して up -d認証情報は必ずCIのSecretsに置き,ログに出さない(シークレット管理の記事参照).コミットハッシュ($GITHUB_SHA)をタグにすると,どのコミットのイメージかが明確になり,問題時に特定のバージョンへ戻すのも容易になる.
イメージの掃除 ― ストレージを溢れさせない
レジストリは放置すると古いイメージでディスクを食い尽くす.CI/CDで毎回pushすると,タグの数がどんどん増える.不要なイメージを定期的に掃除(ガベージコレクション)する.
レジストリのガベージコレクション
# 不要なタグを削除した後,GCで実体を回収
docker exec registry bin/registry garbage-collect
/etc/docker/registry/config.yml
# 定期的にディスク使用量を確認
docker system dfGCは「参照されなくなったレイヤーの実体を回収」する.運用では「最新数バージョンだけ残して古いタグを削除→GC」を定期化するとよい.加えてレジストリのvolume自体もバックアップ対象に含める(イメージは再ビルドできるが,再ビルドコストを考えると保管しておく価値がある).
補論:自前レジストリは「容量・速度・戻せる安心」のあるVPSで
自前レジストリは便利だが,イメージを保管する容量と,push/pullの速度,そして運用の安全性が前提になる.イメージは数百MB単位で積み上がるため,ディスク容量と速度が効く.
高速NVMe・50種類以上のOSテンプレートに対応した国内VPS─シン・VPS─ はNVMe SSDでイメージのpush/pull・GCが高速で,プラン選択で十分なストレージを確保できる.スナップショットでレジストリのvolumeごと退避できるため,レジストリの設定変更やアップグレードも安全に試せる.自前イメージ配布基盤の土台に向く.
レジストリはregistry.example.comのようなサブドメインで公開するのが一般的だ.取り扱い400種類以上のドメイン取得サービス─ムームードメイン─ で取得したドメインにサブドメインを切り,HTTPS+認証で保護すれば,安全な自前レジストリが完成する.
よくある質問(FAQ)
Q1.自前レジストリは個人開発でも要る?
必須ではないが,CI/CDでイメージを配布したい・プライベートイメージを自分の管理下に置きたい・外部サービスの制限を避けたい場合に有効だ.まず公開サービスで始め,必要を感じたら自前化するのもよい.
Q2.HTTPSは必須?
実質必須だ.DockerはHTTPSでないレジストリへのpush/pullを既定で拒否する.前段のNginxでHTTPS終端し,Basic認証も併せて設定するのが標準的な構成だ.
Q3.pushが413エラーで失敗する
前段Nginxのclient_max_body_size 0(無制限)を設定する.イメージのレイヤーは大きいため,既定の上限では弾かれる.
Q4.イメージのバージョン管理はどうする?
コミットハッシュやバージョン番号をタグにする(myapi:1.0,myapi:$GITHUB_SHA).どのコードのイメージかが明確になり,問題時に特定バージョンへ戻せる.
Q5.ディスクが一杯になる
古いタグを削除してガベージコレクション(GC)を定期実行する.CI/CDで毎回pushするとタグが増えるため,「最新数世代だけ残す」運用を仕込む.
Q6.レジストリのバックアップは要る?
イメージは再ビルドできるが,再ビルドコストを考えるとvolumeのバックアップは有用だ.スナップショットや外部保管に含めておくと,復旧が速い.
まとめ ― 自前レジストリでデプロイの自由を得る
プライベートレジストリは,registryコンテナ+HTTPS+認証で構築でき,CI/CDからのpushと本番のpullを自分の管理下で回せる.イメージの掃除を仕込めば,ストレージも溢れない.
今日やるべきことは,registryコンテナをvolume付きで起動し,前段にHTTPS+Basic認証を組むこと.そして1つイメージをpush/pullしてみる.自前の配布基盤を持つ手応えが掴める.
イメージ配布を自分の手に握れば,デプロイの自由度が上がる.容量と速度のあるVPSなら,自前レジストリは個人開発の強力な武器になる.