メインコンテンツまでスキップ

第44章:COPY(必要な物だけ持っていく)📦

「引っ越し」を想像してみてください🏠📦 COPYホストのフォルダ(ビルドコンテキスト)から、イメージの中へ荷物を運ぶ 命令です🚚💨 ここで雑にやると…👇

  • 😭 ビルドが遅くなる(関係ない荷物まで運ぶ)
  • 😱 秘密が混入する(.env や鍵ファイルなど)
  • 😵 キャッシュが死ぬ(毎回全部コピー扱いになって再ビルド地獄)

なので第44章は 「必要な物だけ、順番も意識して持っていく」 を体に覚えます💪😄


🎯 この章のゴール

  • COPY の挙動(src/dest、末尾スラッシュ)を説明できる🙂
  • .dockerignore を書いて「余計な物を運ばない」状態にできる🧹✨
  • Todo API を “やらかし → 改善” で直せる🔧😆

🧠 まず超重要:COPYが参照する「荷物置き場」=Build Context 📦

docker build ..(ドット)って、“このフォルダを荷物置き場にするよ” って意味です📁 つまりここにあるファイルが(除外しない限り)ビルドに送られます🚛💨

そして、その「送る荷物」を減らすのが .dockerignore です🧹 .dockerignore** ワイルドカードや、! での除外取り消し(例外指定)もできます✍️ さらに、「Dockerfile や .dockerignore 自体も除外指定できるけど、ビルドには必要なので送られる(ただし image に COPY はできない)」という挙動もあります⚠️ (Docker Documentation)


📘 COPYの基本ルール(ここだけは暗記級)🧠⚡

Dockerfile の COPY はこう👇 (Docker Documentation)

  • 形式:

    • COPY [OPTIONS] <src> ... <dest>
    • COPY [OPTIONS] ["<src>", ... "<dest>"](空白があるパス向け)
  • 複数 src を指定したら dest はディレクトリ扱い(末尾 / が要る) (Docker Documentation)

  • dest の末尾スラッシュが超大事

    • COPY test.txt /abs/abs という「ファイル」ができる
    • COPY test.txt /abs//abs/test.txt になる (Docker Documentation)
  • src は ビルドコンテキスト基準COPY src/app.ts /app/ みたいに) (Docker Documentation)

  • COPY ../something ... みたいな コンテキスト外参照は自動で潰される../ が削られる) (Docker Documentation)


💥 事故デモ:とりあえず COPY . . で全部持ってくパターン 😇➡️😱

やりがち Dockerfile(悪い例)👇

## 例:Nodeは2026-02時点だと v24 が Active LTS(安定運用向き)✨
## v25 は Current(新しめ)という位置づけ 👀
FROM node:24-bookworm-slim

WORKDIR /app
COPY . . # ← これが「全部引っ越し」😱
## (次章で RUN npm ci などをやる想定)
CMD ["node", "dist/index.js"]

Node の “Active LTS / Current” の扱いは公式のリリース表で確認できます📅(2026-02 時点で v24 が Active LTS、v25 が Current)(nodejs.org)

この状態だと、例えばプロジェクト直下にこんなのがあると…👇

  • node_modules/(激重📦)
  • .git/(不要+情報漏えいの香り😇)
  • .env(秘密!絶対ダメ!🔑)
  • coverage/dist/*.log(不要がち)

ぜーんぶ build context に入って送られがちです🚛💨(=遅い)


🛠️ ハンズオン:Todo APIを「必要最小限コピー」に改善する 🔧✨

1) まず “入れたくない物” を .dockerignore に書く🧹

プロジェクト直下に .dockerignore を作ります✍️ まずは鉄板セット👇(Todo API想定)

## 依存(重い)
node_modules

## ビルド成果物(方針によっては入れない)
dist
coverage

## ローカル設定・秘密
.env
.env.*
*.pem
*.key

## VCS / エディタ
.git
.vscode

## OSゴミ
.DS_Store
Thumbs.db

## ログ
*.log

.dockerignore** で「どの階層でも」を表現できたり、! で例外を作れます(最後にマッチした行が勝つのもポイント)🧠 (Docker Documentation)


2) COPYを「順番」と「範囲」で絞る📦➡️🎯

ここがコツです😄 “変わりにくい物から先に COPY” すると、次章の RUN(依存インストール)でキャッシュが効きやすくなります🔥 (= ソースをちょっと直しただけで npm ci が毎回走る地獄を避ける)

改善例👇(次章のRUNが1行だけ入るけど、意味だけ掴めればOK👌)

FROM node:24-bookworm-slim
WORKDIR /app

## ✅ まずは依存定義だけ(変化が少ない)
COPY package.json package-lock.json ./

## (次章)ここで npm ci するとキャッシュが超効く💨
RUN npm ci

## ✅ 次に、アプリの実コード・設定だけを必要範囲で
COPY tsconfig.json ./
COPY src ./src

## (例)ビルド成果物を作るなら、ここで RUN npm run build(次章以降)
RUN npm run build

CMD ["node", "dist/index.js"]

ポイントまとめ👇

  • COPY . . をやめて 必要なファイルだけ指定
  • ✅ “依存定義 → ソース” の順にして キャッシュを味方にする
  • dist をコンテナ内で作る方針なら、ホストの dist はコピーしない(だから .dockerignore に入れる)

🧰 覚えると強いCOPYオプション(ただし焦らなくてOK)✨

--chown:コピーしたファイルの所有者を変える👤

Linux系コンテナで「root所有になって困る」を避けられます👍 ただし Windowsコンテナでは非対応 です⚠️ (Docker Documentation)

COPY --chown=node:node src ./src

--chmod:権限を付けてコピーする🔐

実行スクリプトに +x 付けたい時などに便利✨ これも Windowsコンテナでは非対応 です⚠️ (Docker Documentation)

COPY --chmod=+x scripts/start.sh /app/scripts/start.sh

--link:キャッシュ再利用が強くなる(BuildKit向け)🚀

「前のレイヤーが変わっても、COPYした層が無駄に壊れにくい」方向に効きます🧠 ただし概念が少し上級なので、「へー便利」くらいでOKです😄 (Docker Documentation)

ちなみに今の Docker は BuildKit が標準(Docker Desktop / Engine v23.0+)なので、こういう新しい挙動が効きやすい土台は整ってます👍 (Docker Documentation)


🆚 COPY と ADD、どっち使うの?🤔

結論:普通は COPY でOK😊 ADD は「URLから取る」「tarを自動展開」などの特殊能力があるやつです🧙‍♂️ Docker公式の best practices でも ADDCOPY の役割分担が整理されています📘 (Docker Documentation)


🤖 AI活用(コピペで使えるプロンプト)✨

1) .dockerignore 候補を出してもらう🧹

「Node/TypeScript のAPIプロジェクト。Docker build を速くしたい。除外すべきファイル/フォルダを .dockerignore 形式で提案して。理由も一言ずつ。」

2) “必要最小限COPY” の提案をもらう📦

「このディレクトリ構成で、最小で動く Dockerfile の COPY 設計を提案して。COPY . . は禁止。キャッシュが効く順番で。」

3) 混入チェック(危ないファイル)🔍

「この Dockerfile だと image に入りうる秘密情報の候補を列挙して。.env や鍵、.git など。」


✅ できたかチェック(3分テスト)⏱️✨

  • .dockerignorenode_modules.env を入れた?🧹
  • Dockerfile から COPY . . を消して、必要な物だけ指定できた?📦
  • COPY test.txt /absCOPY test.txt /abs/ の違いを説明できる?😄 (Docker Documentation)

🧩 つまずきポイントあるある(先回り)🪤😵

  • 😵「.env を入れ忘れてイメージに混入」→ .dockerignore 最優先
  • 😵「COPY src /app したら /app がファイル扱いになった」→ dest の末尾 / を意識 (Docker Documentation)
  • 😵「ビルドが遅い」→ まず .dockerignore、次に COPY の範囲見直し (Docker Documentation)

次の第45章(RUN)では、この “COPYの順番” がそのまま 爆速ビルド🦾⚡ に直結してきます😆 「依存が毎回入れ直しになってツラい…」を一緒に潰しにいきましょう🔥