Docker | 2週間で実務レベルに到達するDocker学習:本番用Dockerfile - Day11

Docker Docker
スポンサーリンク

Day11:本番用Dockerfile(後半)

テーマ:本番運用に耐える“最適化された Dockerfile”を作るための実践テクニックを深掘りする

後半では、前半・中盤で理解した
「マルチステージビルドの仕組みと効果」
をさらに実務レベルへ引き上げます。

ここでは、
キャッシュ最適化・alpine の注意点・セキュリティ強化・本番運用の落とし穴
といった、現場で必ず必要になる知識を丁寧に解説します。


マルチステージビルドを“さらに強くする”キャッシュ最適化

キャッシュを最大限活かす Dockerfile の書き方

Docker は 上から順にレイヤーをキャッシュ します。
そのため、キャッシュを効かせる書き方をするとビルドが爆速になります。

最適化された構造

FROM node:18 AS build
WORKDIR /app

COPY package*.json ./
RUN npm install --production=false

COPY . .
RUN npm run build
Dockerfile

なぜこれが速いのか

  • package.json が変わらない限り、npm install のレイヤーがキャッシュされる
  • コード変更だけなら COPY . . 以降しか再ビルドされない
  • 大規模プロジェクトほど効果が大きい

実務では、
「package.json を先に COPY する」
は必須テクニックです。


node:18-slim と node:18-alpine の違いを深掘りする

slim は「軽量な Debian」

  • 安定性が高い
  • 互換性が高い
  • ほとんどの Node.js ライブラリが問題なく動く

alpine は「超軽量(約5MB)」

  • 速い
  • 小さい
  • しかし musl libc を使うため、
    ネイティブモジュールが動かないことがある(bcrypt など)

実務での結論

  • 迷ったら slim を使う
  • ネイティブ依存がない場合のみ alpine を検討
  • 本番で alpine を使う場合は必ず動作確認が必要

セキュリティ強化:本番イメージで root を使わない

コンテナ内で root のまま動かすのは危険

攻撃者が侵入した場合、
root 権限で OS にアクセスされる可能性があります。

対策:ユーザーを作って切り替える

FROM node:18-slim
WORKDIR /app

RUN useradd -m appuser
USER appuser

COPY --from=build /app /app

CMD ["node", "app.js"]
Dockerfile

これで何が変わるか

  • コンテナ内の権限が最小化される
  • 侵害された場合の被害が限定される
  • セキュリティスキャンでも高評価になる

実務では 非 root 実行は必須 です。


本番運用での“落とし穴”とその回避方法

1. node_modules の扱い

ビルドステージで npm install を行う場合、
runtime ステージにコピーされるのは ビルド済みの node_modules です。

しかし、alpine と slim ではバイナリ互換性が違うため、
build ステージと runtime ステージの OS が違うと壊れる
ことがあります。

例:
build → node:18
runtime → node:18-alpine
→ ネイティブモジュールが壊れる

対策

  • build と runtime は 同じ系統の OS を使う
    (node:18 → node:18-slim は OK)
  • alpine を使うなら build も alpine にする

本番用 Dockerfile の“完成形”を示す

最適化された本番用 Dockerfile

# --- Build Stage ---
FROM node:18 AS build
WORKDIR /app

COPY package*.json ./
RUN npm install --production=false

COPY . .
RUN npm run build

# --- Runtime Stage ---
FROM node:18-slim
WORKDIR /app

RUN useradd -m appuser
USER appuser

COPY --from=build /app /app

CMD ["node", "app.js"]
Dockerfile

この構造が実務で強い理由

  • build と runtime を分離
  • slim で軽量化
  • root を使わない
  • キャッシュ最適化済み
  • セキュリティリスク最小化

これが 本番運用に耐える Dockerfile の基本形 です。


後半まとめ

あなたがここまで理解できていれば、Day11 のゴールは完全達成です。

  • キャッシュを最大限活かす Dockerfile の書き方が分かる
  • slim と alpine の違いを理解して使い分けられる
  • 本番では root を使わない理由が説明できる
  • build と runtime の OS を揃える重要性を理解している
  • 最適化された本番用 Dockerfile を自分で書ける
タイトルとURLをコピーしました