Dockerイメージ取得とジョブ失敗に対するリトライ機構の追加

rails/buildkite-config

Docker イメージのプルがタイムアウトすることでジョブが失敗するケースが散見されたため、イメージ取得とジョブ実行の両方に対してリトライを組み込む変更が加えられました。この変更により、一時的なネットワーク障害でもビルドパイプラインが安定して継続できるようになります。

背景

CI ジョブが Docker イメージのプルで失敗すると、全体が即座にエラー終了し、再実行が必要になるケースが頻発していました。特に exit_status: 18 は Docker のイメージ取得失敗を示すコードであり、従来は自動リトライ対象に含まれていませんでした。そこで、プル失敗時にジョブ全体を再実行できる仕組みを検討することになりました。

この背景から、ビルドコンテキストに automatic_retry_on を拡張し、exit_status: 18 に対してリトライ上限を設定する方針が採られました。また、Docker Compose が提供する pull_policy オプションを利用して、イメージがローカルに無い場合のみプルさせる設定も同時に導入しました。

技術的な変更

pull_policy が複数サービスに追加され、missing が指定されています。これにより、イメージがキャッシュに無いときだけプルが走り、不要なネットワーク呼び出しを減らします。

  memcached:
    image: memcached:alpine
    pull_policy: missing

automatic_retry_onexit_status: 18 が加わり、リトライ回数が 2 回に設定されています。build_context.rb の該当メソッドは以下のように変更されました。

def automatic_retry_on
  [
    { exit_status: -1, limit: 2 },
    { exit_status: 18, limit: 2 },
    { exit_status: 255, limit: 2 },
  ]
end

docker_compose plugin のインストールオプションに pullpull-retries が追加され、イメージ取得時のリトライ回数が 3 回に設定されました。rake_command.rb の変更点は次の通りです。

compose_opts = {
  "env" => env,
  "run" => service,
  "pull" => [service, "--include-deps"],
  "pull-retries" => 3,
  "config" => ".buildkite/docker-compose.yml",
  "shell" => ["runner", *dir],
  "tty" => "true",
}

さらに、rails-ci/pipeline.rbdocs-preview/pipeline.rb のプラグインバージョンが docker-compose#v5.12.1 に統一され、プルリトライ機能を含む最新実装を利用できるようになりました。

plugin :docker_compose, "docker-compose#v5.12.1"

テストコードも同様に更新され、automatic_retry_on に新要素が含まれることや、pull-retries が正しく出力されることを検証しています。テストの一部抜粋は以下です。

assert_equal(
  { "automatic" => [
    { "limit" => 2, "exit_status" => -1 },
    { "limit" => 2, "exit_status" => 18 },
    { "limit" => 2, "exit_status" => 255 },
  ] },
  pipeline.to_h["steps"][0]["retry"]
)

設計判断

リトライ対象をプラグインレベルで包括的に扱う方針が取られました。pull-retries をプラグインオプションに持たせることで、個別サービスごとのリトライロジックを炙り出す必要がなくなり、設定の一元化と保守性向上が実現されています。

同時に、pull_policymissing に限定した点は、キャッシュヒット時の無駄なプルを回避し、ネットワーク負荷とビルド時間の削減を狙ったトレードオフです。missing 以外のポリシーは使用しないことで、予期しないプル動作を防止しています。

automatic_retry_onexit_status: 18 を加えた理由は、Docker のプル失敗がビルド全体の再試行対象として妥当であると判断されたためです。リトライ回数を 2 回に設定したことは、過度な再試行を防ぎつつ、瞬間的な障害に対処できるバランスを取った結果です。

まとめ

本 PR は Docker イメージ取得失敗とジョブ終了コード 18 に対して、プルリトライとジョブ自動再実行の仕組みを導入した点が最大の特徴です。pull_policypull-retries によるイメージ取得の堅牢化と、automatic_retry_on でジョブ全体のリトライを可能にしたことで、CI パイプラインの信頼性が大幅に向上しました。

記事メタデータ

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

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

品質レビュー結果

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

Review Criteria:

記事構成 ✓ PASS

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

リード文・背景・技術的変更・設計判断・まとめの5セクションがあり、総論→各論→結論の流れが明確です。

カスタムMarkdown構文 ⚠ WARNING

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

コードブロックのファイル名付きハイライトは正しい形式ですが、PRリンクが「[PR #185](URL)」となっており、要件の「[#185](URL)」形式になっていません。

対象読者への適合性 ✓ PASS

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

エンジニア向けの専門的な内容で、初心者向けの過度な解説はありません。

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

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

各セクションは総論・各論・結論の段落構成になっており、段落はトピックセンテンスで始まり、長さも適切です。

Diff内容との照合 ✓ PASS

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

記事中のコードブロックはDiffに存在する変更と一致しており、抜粋でも誤りや省略が読者の理解を阻害するレベルではありません。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「pull_policy」や「automatic_retry_on」などの用語はPRで使用されているものと一致し、誤用はありません。

説明の技術的正確性 ✓ PASS

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

技術的な説明はDiffとPRの記述に基づき、根拠があり論理的です。

事実の突合 ✓ PASS

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

全ての主張はPR情報やDiffで裏付けられており、推測や捏造は見られません。

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

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

PR番号#185、リトライ回数2回・3回、exit_status 18 など数値は正確です。

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

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

記事タイトルはPRの内容(Dockerイメージ取得とリトライ機構の追加)を適切に要約しています。

外部知識の正確性 ✓ PASS

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

記事はPRに記載された情報以外の外部知識(LTS、サポート状況等)を付加していません。

時間表現の正確性 ✓ PASS

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

時間表現の歪曲はなく、PRの記述と整合しています。