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レジストリまでの旅
イメージは層の単位でレジストリへ運ばれる
-
build
層を積んでイメージにする
-
tag
リポジトリ名を含む名札を付ける
-
login
IAM の権限で認証する
-
push
ない層だけ送る
-
ECR
リポジトリに置く
-
pull
ECS などが取り出す
docker buildでイメージを作る- IAM の権限(
ecr:GetAuthorizationToken)で認証トークンを得て、docker loginする - ECR のリポジトリ名を含む形でタグを付ける
docker pushで送る- 実行する側が
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 の権限で認証してから使います。
参照ソース
- Amazon ECR とは(Amazon ECR ユーザーガイド) — ECR がマネージドのイメージレジストリであること、IAM による権限、ライフサイクルポリシーとスキャンの位置づけの根拠(2026-10 時点)
- AWS CLI で Amazon ECR を使いはじめる(Amazon ECR ユーザーガイド) — build → 認証 → タグ付け → push → pull の流れと、出力が層ごとに進む点の根拠(2026-10 時点)


