「latestはもちろん避けているが、python:3.12-slimのような固定タグでも本当に同じイメージが降ってくるのか不安だ」
Dockerのイメージタグは、実は「上書き可能な参照」にすぎません。python:3.12-slimのような具体的なタグを指定していても、公式メンテナがベースイメージにセキュリティパッチを当てて同じタグ名のまま再pushすれば、中身(レイヤーの実体)はいつの間にか入れ替わります。「タグを固定しているのにCIだけビルドが壊れた」「開発機と本番で微妙に挙動が違う」という事故の多くは、このタグの可変性が原因です。
この記事では、イメージの中身そのものを一意に特定する「ダイジェスト(sha256ハッシュ)」を使ってDockerfileのFROM命令を固定し、いつビルドしても同じイメージから同じ結果を再現する方法を、Ubuntu 24.04 LTS + Docker 26.1での実機出力を交えて解説します。タグとダイジェストの使い分け、Renovateによる自動更新運用まで、本番運用に耐える設計をカバーします。
この記事のポイント
・Dockerのイメージタグは上書き可能で、同じタグでも中身が変わることがある
・FROM イメージ名@sha256:ハッシュ でダイジェスト固定すると常に同一イメージを取得できる
・docker buildx imagetools inspectでマルチアーキ対応のダイジェストを確認できる
・Renovate等でダイジェストを自動更新すれば安全性と再現性を両立できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜタグ固定だけでは再現性が保証されないのか
Dockerのイメージタグ(例:python:3.12-slim)は、レジストリ内のある時点のダイジェストを指す「ラベル」にすぎません。タグとダイジェストの実体を確認してみましょう。# python:3.12-slimを取得する $ docker pull python:3.12-slim 3.12-slim: Pulling from library/python a378f10b3218: Pull complete 1a4e46412da1: Pull complete Digest: sha256:9c1d9ed7593f2552a4ea47362ce20d6f7a51d2f65b9b9903c73fe8f8ef873b3d Status: Downloaded newer image for python:3.12-slim docker.io/library/python:3.12-slim # RepoDigestsでイメージの実体を確認する $ docker inspect --format='{{.RepoDigests}}' python:3.12-slim [python@sha256:9c1d9ed7593f2552a4ea47362ce20d6f7a51d2f65b9b9903c73fe8f8ef873b3d]
sha256:9c1d9ed...がイメージの中身そのものを表す一意な識別子です。python:3.12-slimというタグは、あくまで「現時点でこのダイジェストを指している」という参照にすぎません。Debianのセキュリティ更新やPythonのパッチバージョンアップに合わせて、公式イメージメンテナが同じタグに新しいレイヤーをpushすれば、翌日には同じdocker pull python:3.12-slimでも別のダイジェストが返ってきます。CIパイプラインで
docker build --pull(常に最新のベースイメージを取得するオプション)を使っていたり、ビルドキャッシュが切れて再pullが走ったりすると、この「見えないベースイメージの入れ替わり」がそのままビルド結果の差異になります。開発機とCIでビルドタイミングがずれるだけで挙動が変わる、いわゆる「手元では動くのに」問題の一因です。基本的な使い方(イメージをダイジェストで固定する)
1. docker pullでダイジェストを取得する
固定したいイメージを一度pullし、RepoDigestsを控えます。先ほどの実行例で取得したsha256:9c1d9ed7593f2552a4ea47362ce20d6f7a51d2f65b9b9903c73fe8f8ef873b3dを使います。公開レジストリ側のダイジェストを直接調べたい場合は、pullせずに
docker manifest inspectでも確認できます。# ローカルに落とさずレジストリ側の情報だけ確認する $ docker manifest inspect python:3.12-slim --verbose | grep -m1 digest "digest": "sha256:9c1d9ed7593f2552a4ea47362ce20d6f7a51d2f65b9b9903c73fe8f8ef873b3d",
2. DockerfileのFROM命令をダイジェスト形式に書き換える
FROM命令はイメージ名@sha256:ハッシュ値という形式でダイジェスト指定を受け付けます。タグと併記することも可能です。# 変更前:タグだけで指定(上書きされる可能性がある) FROM python:3.12-slim # 変更後:ダイジェストで固定する(常に同一イメージ) FROM python:3.12-slim@sha256:9c1d9ed7593f2552a4ea47362ce20d6f7a51d2f65b9b9903c73fe8f8ef873b3d
3. ビルドしてダイジェスト固定を確認する
ダイジェストを指定してビルドすると、ビルドログにも解決済みのダイジェストが表示されます。# ビルドする $ docker build -t myapp:1.0 . [+] Building 12.3s (10/10) FINISHED => [internal] load build definition from Dockerfile => [internal] load metadata for docker.io/library/python:3.12-slim@sha256:9c1d9ed... => CACHED [1/5] FROM docker.io/library/python:3.12-slim@sha256:9c1d9ed7593f2552a4ea47362ce20d6f7a51d2f65b9b9903c73fe8f8ef873b3d => [2/5] WORKDIR /app ... # 翌日、上流でタグが更新されていても--pullを付けて再ビルドしてみる $ docker build --pull -t myapp:1.1 . => CACHED [1/5] FROM docker.io/library/python:3.12-slim@sha256:9c1d9ed7593f2552a4ea47362ce20d6f7a51d2f65b9b9903c73fe8f8ef873b3d
--pullで新しいレイヤーが降ってくる場面でも、ダイジェスト指定ではDockerが「このハッシュのイメージは既にローカルにある」と判断し、常に同一のベースイメージからビルドされます。これがダイジェスト固定によるビルド再現性の実体です。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、本記事で紹介したDockerfile設計をさらに体系立てて学べる、コンテナ概念・Compose・Dockerfile設計を実機ハンズオンで習得できるDocker実践講座(linuxmaster.jp)を用意しています。現役エンジニアが現場目線で、再現性のあるビルド設計から本番運用まで指導します。
応用・実務Tips(タグ運用との使い分けと自動更新設計)
ダイジェスト固定は再現性を保証する一方、「今どのバージョン系列を使っているか」がハッシュだけでは読み取れない弱点があります。実務では次の3点を組み合わせて運用します。・タグ併記:
FROM python:3.12-slim@sha256:...の形式でタグ情報をコメント代わりに残す・マルチアーキ確認:
docker buildx imagetools inspectでプラットフォームごとのダイジェストを確認してから固定する・自動更新:RenovateやDependabotにダイジェストの追従を任せ、人手での更新漏れを防ぐ
マルチアーキイメージのダイジェストを確認する
python:3.12-slimのような公式イメージは、linux/amd64とlinux/arm64など複数プラットフォーム向けのイメージをまとめた「マニフェストインデックス」として配布されています。docker buildx imagetools inspectで全体像を確認できます。$ docker buildx imagetools inspect python:3.12-slim Name: docker.io/library/python:3.12-slim MediaType: application/vnd.oci.image.index.v1+json Digest: sha256:9c1d9ed7593f2552a4ea47362ce20d6f7a51d2f65b9b9903c73fe8f8ef873b3d Manifests: Name: docker.io/library/python:3.12-slim@sha256:2f1a3bce1d1e0e5f2c1a9b7d6e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f MediaType: application/vnd.oci.image.manifest.v1+json Platform: linux/amd64 Name: docker.io/library/python:3.12-slim@sha256:7e4c9d1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e MediaType: application/vnd.oci.image.manifest.v1+json Platform: linux/arm64
Digest(マニフェストインデックス全体のダイジェスト)をFROMに指定すれば、ビルドするマシンのアーキテクチャに応じてDockerが自動的に該当プラットフォームのイメージを選びます。一方、Platform欄に並ぶ個別のダイジェストは特定アーキテクチャ専用の実体で、これをFROMに固定するとそのアーキテクチャでしかビルドできなくなる点に注意してください。Renovateでダイジェストを自動更新する
ダイジェスト固定の唯一の欠点は「セキュリティパッチが出ても自動では追従しない」ことです。これはRenovateのDockerマネージャに任せることで解決できます。# renovate.json(抜粋):Dockerfileのダイジェストをタグ併記のまま自動更新する { "docker": { "pinDigests": true } }
FROM python:3.12-slim@sha256:...のダイジェスト部分だけを書き換えるプルリクエストが自動作成されます。タグ情報は維持されたまま安全に追従できるため、「固定はするが放置しない」運用が実現できます。「manifest unknown」「no matching manifest」が出た時の対処法
ダイジェスト固定を運用していると、次の2つのエラーに遭遇することがあります。1. 「manifest unknown」でpull・buildが失敗する
$ docker build -t myapp . [+] Building 0.4s (2/8) => ERROR [internal] load metadata for docker.io/library/python:3.12-slim@sha256:0000000000000000000000000000000000000000000000000000000000000 ------ failed to solve: python:3.12-slim@sha256:0000...: python:3.12-slim@sha256:0000...: not found
docker manifest inspectで最新のダイジェストを再取得し、Dockerfileを更新してください。2. 「no matching manifest for linux/arm64」が出る
$ docker buildx build --platform linux/arm64 -t myapp . ERROR: failed to solve: python:3.12-slim@sha256:2f1a3bce...: no match for platform in manifest: not found
docker buildx imagetools inspectの出力で先頭に表示されるマニフェストインデックスのDigest(Platform欄が付いていない方)をFROMに指定し直すことです。本記事のまとめ
| やりたいこと | コマンド |
|---|---|
| 現在のダイジェストを確認する | docker inspect --format='{{.RepoDigests}}' イメージ名 |
| レジストリ側のダイジェストだけ確認する(pull不要) | docker manifest inspect イメージ名 --verbose |
| FROM命令をダイジェストで固定する | FROM イメージ名@sha256:ハッシュ値 |
| マルチアーキのダイジェスト一覧を見る | docker buildx imagetools inspect イメージ名 |
| ダイジェストを自動更新する | Renovateのdockerマネージャ(pinDigests: true) |
Dockerfile設計の再現性・セキュリティを体系的に習得したい方は、Docker実践講座(linuxmaster.jp)をご覧ください。コンテナの基礎からCompose設計、CI/CD連携まで、現役エンジニアが現場目線で教えるハンズオン形式で学べます。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:Dockerのファイル権限エラーを解決する方法|ホストとコンテナのUID・GIDズレをUSER命令とPUID・PGIDで防ぐ設計
- この記事の属するカテゴリ:Dockerへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます