Dockerイメージ取得とジョブ失敗に対するリトライ機構の追加
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_on に exit_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 のインストールオプションに pull と pull-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.rb と docs-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_policy を missing に限定した点は、キャッシュヒット時の無駄なプルを回避し、ネットワーク負荷とビルド時間の削減を狙ったトレードオフです。missing 以外のポリシーは使用しないことで、予期しないプル動作を防止しています。
automatic_retry_on に exit_status: 18 を加えた理由は、Docker のプル失敗がビルド全体の再試行対象として妥当であると判断されたためです。リトライ回数を 2 回に設定したことは、過度な再試行を防ぎつつ、瞬間的な障害に対処できるバランスを取った結果です。
まとめ
本 PR は Docker イメージ取得失敗とジョブ終了コード 18 に対して、プルリトライとジョブ自動再実行の仕組みを導入した点が最大の特徴です。pull_policy と pull-retries によるイメージ取得の堅牢化と、automatic_retry_on でジョブ全体のリトライを可能にしたことで、CI パイプラインの信頼性が大幅に向上しました。