FOR LEARNERS学習中向け

D開発の道具段2構成層仕組み

Docker イメージの仕組み|レイヤー・タグとダイジェスト・push と pull で何が運ばれるか

Docker イメージの仕組み|レイヤー・タグとダイジェスト・push と pull で何が運ばれるか

docker build や docker push を打つと、長い英数字の列が並んで流れます。ビルドは速いときと遅いときがあり、latest が何を指しているのかも曖昧なまま、という人は多いはずです。原因の多くは、イメージを「1つの大きなファイル」と思っていることにあります。この記事では、イメージを層の積み重ねとして捉え直し、ビルド・タグ・push が何をしているかを順に説明します。

この記事の結論

  • イメージは読み取り専用の層(レイヤー)の積み重ねで、Dockerfile の命令(FROM・RUN・COPY など)が層を作ります。
  • コンテナを起動すると、その上に書き込める層が1枚載ります。コンテナを消すと、その層も消えます。
  • 変更のない層は再利用(キャッシュ)されるので、変わりにくい命令を上、変わりやすい命令を下に書くとビルドが速くなります。
  • タグ(latest など)は付け替えられる名札、ダイジェスト(sha256:…)は中身で決まる固定の識別子です。
  • レジストリ(Amazon ECR・Docker Hub など)は層単位で push・pull する置き場で、すでにある層は送り直しません。
  • ECR へ push する前に、IAM の権限で認証トークンを得て docker login します。

Docker イメージの正体は何か|読み取り専用の層の積み重ね

前の記事( READ ALSO — 学習中向け・段2 構成 Docker(コンテナ)とは|イメージ・コンテナ・Dockerfile と仮想マシンとの違い )では、イメージを「アプリと必要な部品を詰めた、実行前の設計図」と説明しました。もう一歩踏み込むと、イメージは層(レイヤー)を下から積み重ねたものです。各層は「ここで何が増えた・変わったか」の差分を持ち、いったんできた層は書き換えられません。

イメージの層は読み取り専用です。コンテナを起動すると、その一番上に書き込める層が1枚だけ載ります。コンテナの中で作ったファイルや書き換えは、この層に入ります。

LAYERS OF AN IMAGEイメージは層の積み重ね

イメージは読み取り専用の層で、書き込めるのはコンテナの1枚だけ

イメージ

  • FROM(ベースの層)
  • RUN(パッケージ導入の層)
  • COPY(アプリの層)
  • 書き込み層(コンテナだけ)

コンテナ

  • FROM(ベースの層)
  • RUN(パッケージ導入の層)
  • COPY(アプリの層)
  • 書き込み層(コンテナだけ)

書き込める層読み取り専用の層

コンテナを消すと書き込み層も消える。イメージの層は変わらない

ここで大事な帰結が2つあります。

  • コンテナの中で書いたものは、イメージには入りません。 同じイメージから起動した別のコンテナは、元の状態から始まります。残したいデータは、コンテナの外の置き場に出す設計にします。
  • 同じイメージから、いくつでもコンテナを起動できます。 土台の層は共有され、コンテナごとに違うのは一番上の書き込み層だけです。

CHECK 1ここまでの確認

コンテナの中で新しく作ったファイルは、元のイメージに入るか?

答えと解説

答え: 2. 入らない。書き込みはコンテナ専用の層に載り、コンテナを消すと一緒に消える

イメージの層は読み取り専用で、コンテナを起動するとその上に書き込める層が1枚載るだけです。「Dockerfile の1行が1層になる仕組みと、コンテナの書き込み層」を読み直してください。

Dockerfile の1行が1層になる仕組みと、コンテナの書き込み層

Dockerfile は、イメージの作り方を上から順に書いた文書です。docker build は命令を上から順に実行し、命令の結果を層として積んでいきます。

FROM python:3.12-slim
RUN pip install flask
COPY app.py /app/app.py
CMD ["python", "/app/app.py"]

この例では、おおまかに次のように対応します。

命令 何を足すか 層になるか
FROM 土台になるベースイメージ(それ自体が層の束) ベースの層を引き継ぐ
RUN コマンドを実行した結果(パッケージの導入など) ファイルが変わるなら層になる
COPY 手元のファイルをイメージに入れる 層になる
CMD 起動時に実行するコマンドの設定 中身は増やさず、設定として持つ

つまり「Dockerfile を1行足すと、イメージに1枚足される」と考えると、あとの話が分かりやすくなります。ベースイメージはすでに複数の層でできているので、自分で足した層は、その上に積む分です。

ビルドが速いとき・遅いときの違いは何か|層のキャッシュと命令の順番

同じ Dockerfile を2回ビルドすると、2回目は一瞬で終わることがあります。命令も、その入力(COPY するファイルなど)も前回と同じ層は、作り直さず再利用されるためです。これが層のキャッシュです。

注意したいのは、ある層が変わると、それより後ろの層はすべて作り直しになることです。下の図の左右は、同じ中身を別の順番で書いたものです。

ORDER MATTERS命令の並びとタグ

変わりにくい命令を上に置くとキャッシュが効く

遅くなる並び・名札だけの指定

速くなる並び・固定する指定

遅くなる並び・名札だけの指定: ソースの COPY → パッケージ導入

速くなる並び・固定する指定: パッケージ導入 → ソースの COPY

遅くなる並び・名札だけの指定: ソースを直すたび、導入からやり直し

速くなる並び・固定する指定: ソースだけ直せば、導入はキャッシュから

遅くなる並び・名札だけの指定: タグ(latest)は付け替えられる

速くなる並び・固定する指定: ダイジェストは中身で決まる

ある層が変わると、それより後ろの層はすべて作り直しになる

ソースコードは毎日のように直すので、ソースの COPY を先に書くと、直すたびにその後ろのパッケージ導入まで毎回やり直しになります。パッケージの導入を先に書き、ソースの COPY を後ろに回せば、ソースだけを直したときは導入の層をキャッシュから使えます。

# 変わりにくい順に上から書く
FROM python:3.12-slim
COPY requirements.txt /app/requirements.txt
RUN pip install -r /app/requirements.txt
COPY . /app

これは「変わりにくいものを上、変わりやすいものを下」という原則の具体例です。

CHECK 2ここまでの確認

アプリのソースを頻繁に直す場合、Dockerfile ではどちらを先に書くと再ビルドが速くなりやすい?

答えと解説

答え: 2. パッケージの導入を先、ソースの COPY を後

ある層が変わると、それより下(後ろ)の層は作り直しになります。変わりにくい命令を先に置くと、その層をキャッシュから再利用できます。

タグとダイジェストの違い|「latest」が指すものは動く

イメージを指す名前には2種類あります。

呼び名 例 性質
タグ myapp:latest、myapp:1.4 人が付ける名札。別のイメージに付け替えられる
ダイジェスト myapp@sha256:… イメージの中身から決まる識別子。中身が変われば変わる

latest は「最新を自動で指す特別な名前」ではなく、ただのタグの1つです。新しいイメージを同じタグで push すれば、同じ名前が別の中身を指すようになります。昨日の myapp:latest と今日の myapp:latest が同じ中身とは限りません。

このため、版を固定したいときの考え方は次のとおりです。

  • 人が読んで管理しやすい版のタグ(1.4 など)を使い、運用で「同じタグを上書きしない」と決める
  • 厳密に固定したいなら、ダイジェストで指定する

push や pull の画面に出る長い英数字の列の多くは、層やイメージを識別するダイジェストです。人が覚えるためのものではなく、中身が同じかを機械が確かめるための名前だと理解しておけば十分です。

CHECK 3ここまでの確認

昨日と今日で、同じタグ名が別の中身を指していることはありうる?

答えと解説

答え: 2. ありうる。固定したいならダイジェストを使う

タグは付け替えられる名札で、ダイジェストは中身から決まる識別子です。「タグとダイジェストの違い」の節を読み直してください。

レジストリとは何か|ECR に push・pull するとき層単位で運ばれる

レジストリは、イメージを置いて、必要な場所から取り出せるようにする置き場です。AWS では Amazon ECR(Elastic Container Registry) がマネージドのコンテナイメージのレジストリで、ECS や EKS などから pull できます。独自のライブラリを含む環境が必要で、既存のコンテナでは動かないときも、自分でイメージを作って ECR に登録して使う、という流れになります。

流れは、公式のはじめかたの手順でも次の順に整理されています。

BUILD, PUSH, PULLレジストリまでの旅

イメージは層の単位でレジストリへ運ばれる

  1. build

    層を積んでイメージにする

  2. tag

    リポジトリ名を含む名札を付ける

  3. login

    IAM の権限で認証する

  4. push

    ない層だけ送る

  5. ECR

    リポジトリに置く

  6. pull

    ECS などが取り出す

出典: Amazon ECR ユーザーガイド(What is Amazon ECR? / Getting started with the AWS CLI)
  1. docker build でイメージを作る
  2. IAM の権限(ecr:GetAuthorizationToken)で認証トークンを得て、docker login する
  3. ECR のリポジトリ名を含む形でタグを付ける
  4. docker push で送る
  5. 実行する側が docker pull で取り出す

push や pull の出力を見ると、層ごとに 「Pushed」「Pull complete」と進捗が出ます。レジストリとの間では、イメージ全体ではなく層の単位で運ばれます。すでにレジストリにある層は送り直さないので、ソースだけを直したイメージの push は、変わった層だけで済みます。ここでも「変わりにくい層を上に」という並び方が効いてきます。

ECR のプライベートリポジトリの権限は IAM で絞ります。誰が push でき、誰が pull できるかを、IAM のポリシーで分けられるのが、AWS のサービスから使うときの利点です。コマンドの細かい手順は、改定で変わるので公式の「はじめに」に任せます。

CHECK 4ここまでの確認

Amazon ECR のプライベートリポジトリへ push する前に、まず何が要る?

答えと解説

答え: 1. IAM の権限で認証トークンを取り、docker login する

ECR は IAM で権限を絞るレジストリで、push や pull の前に認証が要ります。「レジストリとは何か」の節を読み直してください。

イメージが大きくなる・古くなるときの見直し点

層の仕組みを知っていると、イメージを軽くする見直しの方向が見えてきます。

  • 不要なものを入れない。 一度層に入れたファイルは、あとの層で消しても、前の層の中には残っています。入れる前に絞るのが基本です。
  • ベースイメージを見直す。 必要なものだけの軽いベースにすると、pull と起動が軽くなります。
  • 古いイメージを溜め込まない。 ECR にはライフサイクルポリシーがあり、古いイメージを自動で整理する考え方を取れます。料金の数値は公式の料金ページで確認してください。
  • 脆弱性の検査を前提にする。 ECR には push されたイメージのスキャンがあり、新しい脆弱性が公開されたあとも継続して検査したいときは、Amazon Inspector と連携する拡張スキャンを使う、という整理です。設定の詳細は公式に任せます。

Cloudory 執筆者(AWS 認定 全冠)

イメージを「ファイル」ではなく「層の列」と見ると、ビルドの速さ・push の軽さ・タグの落とし穴が一つの話につながります。次は、できたイメージを走らせ続ける ECS の仕組みに進んでください。

まとめ

  • イメージは読み取り専用の層の積み重ね。コンテナはその上に書き込み層を1枚載せたもので、消すと書き込みも消えます。
  • 変わりにくい命令を上、変わりやすい命令を下に書くと、キャッシュが効いてビルドが速くなります。
  • タグは付け替えられる名札、ダイジェストは中身で決まる識別子。版を固定するなら、バージョンのタグかダイジェストです。
  • ECR などのレジストリへは層単位で push・pull されます。ECR では IAM の権限で認証してから使います。

参照ソース

SCOREこの記事の確認テスト

0/4問 正解

各章の「ここまでの確認」に答えると、ここに集まります。結果はこの端末のブラウザにだけ残り、サーバには送りません。

PRACTICEこの記事の論点を練習問題で確かめる

この記事が扱うサービスの問題だけを続けて解けます。練習問題は Google でログインした人が使えます(練習問題の一覧)。

HAND IT OVER人に渡すなら

一言で説明するなら

イメージは、薄い透明シートを何枚も重ねた設計図です。変わった一枚だけ差し替えれば済むので、運ぶのも作り直すのも軽くなります。

前提を持たない人にそのまま渡せる記事です。「後輩に説明する」「顧客に理由を伝える」の材料として。

FAQよくある質問

ECR と Docker Hub のどちらを使えばよいか?

AWS のサービスから IAM で権限を絞ってイメージを取らせたいなら ECR が素直です。広く公開・共有することが目的なら、そのための置き場を選びます。料金は公式の料金ページで確認してください。

イメージが大きいと何が困るか?

push と pull に時間がかかり、コンテナの起動も遅くなりやすくなります。不要な層やファイルが混ざっていないかを見直します。

latest タグを本番で使ってよいか?

latest が指す中身は付け替えられて動くので、版を固定したいときはバージョンを入れたタグかダイジェストで指定する考え方が安全です。

次に何を読むとよいか?

作ったイメージを実際に走らせ続ける仕組みとして、ECS の仕組み(ecs-shikumi)に進んでください。

SAME TRACK同じ領域の記事

JSON と YAML の読み方|設定ファイルが「入れ子の名前と値」でできている仕組み
JSON と YAML の読み方|設定ファイルが「入れ子の名前と値」でできている仕組み 段0 土台仕組み
Git とは何か|「上書き保存」と「版を残す」の違いを、最初の3つの動作で理解する
Git とは何か|「上書き保存」と「版を残す」の違いを、最初の3つの動作で理解する 段0 土台とは
Git のブランチとマージの仕組み|main を直接触らない理由と、プルリクエスト・衝突の意味
Git のブランチとマージの仕組み|main を直接触らない理由と、プルリクエスト・衝突の意味 段1 入口仕組み