0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Dockerfileの依存関係とキャッシュを理解する――なぜ毎回インストールされるのか

0
Last updated at Posted at 2026-09-09

Dockerfileを読み始めたとき、WORKDIRを指定しているのにCOPY requirements.txt .と書ける理由や、--no-cache-dirを付けてもDockerのキャッシュが効く理由が分かりませんでした。コピー元・コピー先と、キャッシュの違いを整理します。

WORKDIRが変えるのはコンテナ側の基準位置

次の2行を見てみます。

WORKDIR /app
COPY requirements.txt .

COPYCOPY <コピー元> <コピー先>という構文です。

  • 左側のrequirements.txtは、docker build .の最後の.で指定したビルドコンテキストが基準
  • 右側の.は、イメージ内の現在の作業ディレクトリ、つまり/app

つまり、requirements.txtをイメージ内の/app/requirements.txtへコピーしています。WORKDIRはホスト側のコピー元を変える命令ではありません。

OSとPythonの依存関係は別々に入る

Debian系のPythonイメージでは、例えば次のような処理が登場します。

FROM python:3.12-slim-bookworm

ARG NODE_MAJOR=24
WORKDIR /app

RUN apt-get update \
    && apt-get install -y --no-install-recommends ca-certificates curl \
    && curl -fsSL "https://deb.nodesource.com/setup_${NODE_MAJOR}.x" \
       -o /tmp/nodesource_setup.sh \
    && bash /tmp/nodesource_setup.sh \
    && apt-get install -y --no-install-recommends nodejs \
    && rm -f /tmp/nodesource_setup.sh \
    && rm -rf /var/lib/apt/lists/*

COPY requirements.txt .
RUN python -m pip install --no-cache-dir -r requirements.txt

処理の流れは次のとおりです。

  1. apt-get updateでAPTのパッケージ一覧を取得する
  2. curlなど、後続処理に必要なOSパッケージを入れる
  3. NodeSourceのスクリプトで、指定系列のNode.jsを取得できるAPTリポジトリを設定する
  4. apt-get install nodejsでNode.js本体を入れる
  5. python -m pipで、そのpythonに対応するpipを実行してPythonパッケージを入れる

NodeSourceのスクリプト自体はNode.js本体ではありません。外部から取得したスクリプトを実行するため、配布元と内容の確認も必要です。python -m pipは「どのPythonのpipか」を明確にします。

なお、Node.js 20は2026年4月30日にEOLを迎えています。新規構築では、使用中のNode.js系列がサポート期間内か確認が必要です。

3種類のキャッシュを分けて考える

対象 役割 この例での扱い
APTのパッケージ一覧 OSパッケージの検索に使う /var/lib/apt/lists/*を削除
pipキャッシュ ダウンロード済みファイルやwheelを再利用する --no-cache-dirで無効化
Dockerビルドキャッシュ Dockerfileの命令結果をレイヤー単位で再利用する 上の2つとは独立

--no-cache-dirを指定しても、RUN python -m pip install ...の結果はDockerレイヤーとして再利用できます。APTの一覧を削除しても同様です。

COPYの順序で再インストールを防ぐ

次の順序では、コードを1ファイル変えただけでもCOPY . .がキャッシュミスし、後続のpip installも再実行されます。

COPY . .
RUN python -m pip install --no-cache-dir -r requirements.txt

依存ファイルを先にコピーすれば、コードだけを変えたビルドではインストール済みレイヤーを再利用できます。

COPY requirements.txt .
RUN python -m pip install --no-cache-dir -r requirements.txt

COPY . .

依存ファイルを本番用と開発用に分ける場合も考え方は同じです。

COPY requirements.txt .
RUN python -m pip install --no-cache-dir -r requirements.txt

COPY requirements-dev.txt .
RUN python -m pip install --no-cache-dir -r requirements-dev.txt

requirements-dev.txtだけを変えれば、本番用依存のレイヤーは再利用できます。一方、先のrequirements.txtを変えると後続も再実行されます。ファイルを分けても、後続レイヤーが前段の変更から独立するわけではありません。

まとめ

  • COPYのコピー元はビルドコンテキスト、相対的なコピー先はWORKDIRが基準
  • NodeSourceのセットアップ処理はリポジトリを設定し、Node.js本体はAPTがインストールする
  • python -m pipは、実行するPythonとpipの対応を明確にする
  • pipやAPTのキャッシュと、Dockerのビルドキャッシュは別の仕組み
  • 変更頻度の低い依存ファイルを先にCOPYすると、重いインストール処理を再利用しやすい

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?