Renovate で ECR pull-through cache 経由のイメージにも minimumReleaseAge を適用できるか検証してみた
はじめに
製造ビジネステクノロジー部のふじい(大)です。
Renovate を使った Docker イメージ更新の運用で、minimumReleaseAge (リリースから一定期間待ってから更新提案する機能、サプライチェーン攻撃対策に有効) を有効化したいと思ったときに、ECR を経由したイメージ参照では機能しないという壁にぶつかりました。実体が Docker Hub のイメージである pull-through cache 経由のケースでも例外ではなく、ここがハマりどころでした。
公式ドキュメントの記載と Renovate のソースコードを追跡したところ、回避策として registryAliases という設定が使えそうだと分かったので、ローカル環境で動作検証してみました。
TL;DR
- Renovate の
minimumReleaseAgeは Docker Hub レジストリでのみ対応 (ECR / GHCR / Quay は非対応) - ECR pull-through cache 経由で Docker Hub のイメージを参照している場合、デフォルトでは
minimumReleaseAgeが効かない registryAliases設定で内部的にメタデータ取得を Docker Hub に向けることで対応できる- ローカルの Dev Container + Renovate Docker イメージで動作検証可能 (本番 AWS への影響ゼロ、コストゼロ)
何が問題なのか
minimumReleaseAge は 「公開から N 日経過しないと更新提案しない」 という設定で、新しく公開された (悪意ある可能性のある) パッケージへの即時更新を防ぐためのサプライチェーン対策機能です。
ところが Renovate の公式ドキュメントには次のような記載があります。
| Datasource | Registry URL | Supported |
|---|---|---|
| docker | https://index.docker.io | ✅ |
| docker | (not Docker Hub) | ❌ |
| docker | https://ghcr.io | ❌ |
| docker | https://quay.io | ❌ |
つまり Docker Hub 以外のレジストリでは releaseTimestamp が取得できず、cooldown 判定ができないということです。
これは Renovate のソースコードを見るとはっきりします。
getDockerHubTags() は hub.docker.com/v2/repositories/.../tags という Docker Hub 独自の Web API を叩いて tag_last_pushed フィールドを取得しますが、それ以外のレジストリでは標準の Docker Registry HTTP API v2 を使うため、タグ名しか取れません。
ECR pull-through cache の問題
ECR の pull-through cache を使って Docker Hub のイメージをミラーする運用は、Docker Hub の pull rate limit 回避や CI 経路の高速化の観点でよく行われます。例えば次のような image 参照です。
image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/dockerhub/library/alpine:3.18.0
Renovate から見るとこの image のレジストリホストは ECR (123456789012.dkr.ecr.us-east-1.amazonaws.com) であり、Docker Hub ではないため、minimumReleaseAge が機能しません。
「実体は Docker Hub のイメージなのに、ECR ミラー経由なせいで cooldown が効かない」 という状況に陥ります。
registryAliases による回避策
Renovate には registryAliases という設定があり、これを使うと 特定のレジストリプレフィックスを別のレジストリに読み替える ことができます。
{
"registryAliases": {
"123456789012.dkr.ecr.us-east-1.amazonaws.com/dockerhub": "docker.io"
}
}
この設定により、Renovate は内部的に以下のように動作します。
| フィールド | 役割 | 例 |
|---|---|---|
replaceString |
ファイル書き換え時の対象文字列 (元の ECR URL を保持) | 123456789012.dkr.ecr.us-east-1.amazonaws.com/dockerhub/library/alpine:3.18.0 |
depName |
PR 表示用の名前 | 123456789012.dkr.ecr.us-east-1.amazonaws.com/dockerhub/library/alpine |
packageName |
レジストリへの問い合わせ用 (Docker Hub に書き換わる) | docker.io/library/alpine |
実装は lib/modules/manager/dockerfile/extract.ts の getDep() 関数にあります。
これで「lookup は Docker Hub に向けて releaseTimestamp を取得、ファイル書き換えは元の ECR URL を保持」という両取り構成が実現できます。
動作検証
実際に動くのかをローカル環境で検証してみます。今回の検証で重要なポイントは以下の通りです。
--platform=localモードを使うと Renovate は image を物理的に pull しない- メタデータ API のみ叩くので、本番 ECR への接続性や AWS 認証情報は不要
- 本番 AWS への副作用ゼロ、コストゼロで完結
検証用ファイルの作成
検証用ディレクトリで Dockerfile と renovate.json を用意します。
# Dockerfile
FROM 123456789012.dkr.ecr.us-east-1.amazonaws.com/dockerhub/library/alpine:3.18.0
// renovate.json
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended"],
"registryAliases": {
"123456789012.dkr.ecr.us-east-1.amazonaws.com/dockerhub": "docker.io"
},
"packageRules": [
{
"description": "Docker イメージ全般に 3 日 cooldown を適用",
"matchDatasources": ["docker"],
"minimumReleaseAge": "3 days",
"internalChecksFilter": "strict"
}
]
}
--platform=local モードは git 履歴を読むので、最低 1 commit を作っておきます。
git init -q
git add Dockerfile renovate.json
git -c user.email=test@example.com -c user.name=test commit -q -m "test setup"
Renovate を Docker で実行
公式の Renovate Docker イメージを使って検証ディレクトリに対して実行します。
docker run --rm \
-v "$(pwd):/usr/src/app" \
-w /usr/src/app \
-e LOG_LEVEL=debug \
renovate/renovate:latest \
--platform=local --autodiscover=false \
2>&1 | tee renovate.log
ログから検証ポイントを確認
1. registryAliases で packageName が書き換わっている
grep -E '"depName"|"packageName"' renovate.log | head -5
"depName":"123456789012.dkr.ecr.us-east-1.amazonaws.com/dockerhub/library/alpine"
"packageName":"docker.io/library/alpine"
packageName が docker.io/library/alpine に書き換わっています。
2. releaseTimestamp が取得できている
grep -E "releaseTimestamp|currentVersionTimestamp" renovate.log | head -5
"releaseTimestamp":"2026-04-15T23:24:30.038Z"
"currentVersionTimestamp":"2023-05-09T23:14:15.563Z"
Docker Hub から releaseTimestamp を取得できています。これが本検証で確認したかった核心部分です。
3. Docker Hub の Web API に通信している
grep "hub.docker.com" renovate.log | head -5
DEBUG: Using queue: host=hub.docker.com, concurrency=16
"hub.docker.com": {"count": 3, ...}
ECR ではなく hub.docker.com に対して問い合わせが行われている ことが確認できます。
4. 更新候補とその年齢
ログには更新候補の詳細も出力されます。
{
"depName": "123456789012.dkr.ecr.us-east-1.amazonaws.com/dockerhub/library/alpine",
"packageName": "docker.io/library/alpine",
"currentValue": "3.18.0",
"currentVersionTimestamp": "2023-05-09T23:14:15.563Z",
"currentVersionAgeInDays": 1099,
"updates": [
{
"newValue": "3.23.4",
"releaseTimestamp": "2026-04-15T23:24:30.038Z",
"newVersionAgeInDays": 27,
"updateType": "minor"
}
],
"registryUrl": "https://index.docker.io",
"lookupName": "library/alpine"
}
newVersionAgeInDays: 27 で minimumReleaseAge: "3 days" の閾値を超えているため、この更新候補は採用されています。もし 3 日以内のリリースが候補だった場合は "pending" 扱いで PR が抑制される、という動作になります。
おわりに
Renovate の minimumReleaseAge を ECR pull-through cache 経由のイメージにも適用したい、というニッチな要件でしたが、registryAliases 設定で解決できることをローカル検証で確認できました。
--platform=local モードを使えば本番 AWS に一切触らず、コストゼロでこの手の Renovate 設定検証ができるので、設定変更を本番に投入する前のチェックに便利です。







