リモートビルダー使用時にローカルレジストリが自動起動されない問題を解消

basecamp/kamal

リモートビルダーでローカルレジストリを指定すると、レジストリコンテナが停止していた場合にデプロイが失敗していました。この PR は、レジストリ起動と認証を別々に制御し、コンテナの自動起動を保証するように変更しています。

背景

builder.remote とローカルレジストリ (registry.server: localhost:5555) を組み合わせてデプロイすると、レジストリコンテナが停止していると connection refused エラーが発生します。原因は、Kamal::Cli::BuildKAMAL.builder.login_to_registry_locally? という単一のフラグで、リモートビルダーの認証とローカルレジストリの起動の二つの意味合いを同時に制御していたことにあります。

このフラグは #1664 でリモートビルダーの認証をスキップするために変更されましたが、同時にローカルレジストリの起動ロジックも無効化してしまいました。その結果、リモートビルダーはレジストリコンテナが存在しない状態でプッシュを試み、dial tcp [::1]:5555: connect: connection refused というエラーになるケースが増えていました。

したがって、リモートビルダーでもローカルレジストリが常に起動していることを保証する必要があります。

技術的な変更

push メソッド内で setup_local_registrylogin_to_registry_locally の呼び出し条件を分離しました。新しい条件は、KAMAL.registry.local? が真なら必ず setup_local_registry を実行し、KAMAL.registry.local? が偽かつ KAMAL.builder.login_to_registry_locally? が真の場合にのみ login_to_registry_locally を実行します。

元の実装では login_to_registry_locally if KAMAL.builder.login_to_registry_locally? が唯一のガードとなり、ローカルレジストリでもリモートビルダーでも同じフラグで制御されていました。このため、リモートビルダーがローカルレジストリを使うケースでレジストリ起動がスキップされていました。

新実装では setup_local_registryKAMAL.registry.local? のみで判定され、レジストリがローカルかどうかに関係なく必ず起動処理が走ります。起動処理は docker start kamal-docker-registry || docker run … registry:3 という 冪等 なコマンドであり、毎回呼び出しても安全です。

login_to_registry_locally はローカルレジストリ以外でだけ実行され、リモートレジストリに対する docker login のみを担当します。これにより #1664 の「リモートビルダーでローカル認証を行わない」方針はそのまま保持されます。

設計判断

責務の分離 を明確にした点が本変更の核心です。レジストリの起動と認証は本質的に別の操作であるにもかかわらず、以前は同一フラグで管理されていました。フラグを分割して条件式を明示的に書くことで、意図しない副作用を防ぎ、コードの可読性も向上しました。

また、後方互換性 を重視し、既存の KAMAL.builder.login_to_registry_locally? の挙動は変更せずに残しました。ローカルレジストリを利用する従来のビルダー(ローカルビルダー)でも同様に setup_local_registry が呼び出され、動作に差異はありません。

テスト面でも、リモートビルダー+ローカルレジストリの組み合わせでレジストリコンテナが起動することを検証する新規テストを追加し、既存のリモートビルダー認証スキップテストが引き続き通過することを確認しています。この回帰テストにより、将来的な変更で同様の問題が再発するリスクを低減しています。

まとめ

push のフローを setup_local_registrylogin_to_registry_locally に分割し、ローカルレジストリの自動起動を保証することで、リモートビルダー使用時のデプロイ失敗を防止しました。結果として、ローカルレジストリとリモートビルダーの組み合わせが安全に利用できるようになり、既存の認証回避ロジックはそのまま維持されています。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
6b678a76

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文、背景、技術的変更、設計判断(任意)およびまとめが明確に分かれており、総論→各論→結論の流れが保たれています。

カスタムMarkdown構文 ⚠ WARNING

シンタックスハイライト・GitHubリンク記法の正確性

コードブロックは使用されていませんが、PRリンクが [PR #1849](URL) の形式で、仕様の [#1849](URL) とは少し異なります。リンク形式を統一するとより良いです。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

専門的な用語と実装詳細にフォーカスしており、エンジニア向けとして適切です。初心者向けの過度な説明はありません。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションは総論→各論→結論の構成で、段落は1トピックに絞られ、トピックセンテンスが冒頭に配置されています。段落長も適切です。

Diff内容との照合 ⚠ WARNING

コードブロックとDiff内容の一致

記事内にコードブロックがなく、Diffとの直接照合ができません。変更概要は記述されていますが、コード例を追加すると完全な照合が可能になります。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

KAMAL.builder.login_to_registry_locally?、KAMAL.registry.local? など、PRで使用されている用語と正確に一致しています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

技術的な説明はPRの内容と合致しており、因果関係も論理的です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事の主張はすべてPRのタイトル、説明、Diffで裏付けられており、ハルシネーションは見られません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号 #1849 や参照番号 #1664、#1679 など、数値・固有名詞は正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事タイトルは PR の目的「リモートビルダーでローカルレジストリを起動させる」ことを日本語で適切に表現しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事は PR に記載された情報のみを使用しており、外部のバージョンサポート情報等は含まれていません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

時間表現は使用しておらず、PRの記述と矛盾はありません。