Dockerfile
Docker
ベストプラクティスとマルチステージビルド
Dockerfileの命令
FROM、RUN、COPY、CMD、ENTRYPOINT など
# ベースイメージ
FROM node:20-alpine
# メタデータ
LABEL maintainer="you@example.com" version="1.0"
# 環境変数
ENV NODE_ENV=production \
PORT=3000
# 作業ディレクトリ
WORKDIR /app
# ファイルコピー(.dockerignore が適用される)
COPY package*.json ./
# コマンド実行(レイヤーをキャッシュ活用)
RUN npm ci --only=production
# アプリコードをコピー(依存関係の後)
COPY . .
# ポート公開(ドキュメント目的、実際はrunで指定)
EXPOSE 3000
# ヘルスチェック
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget -qO- http://localhost:3000/health || exit 1
# 実行ユーザー(rootを避ける)
USER node
# コンテナ起動コマンド
CMD ["node", "server.js"]
# ENTRYPOINT と CMD の違い:
# ENTRYPOINT: 固定コマンド(上書き不可)
# CMD: デフォルト引数(docker run で上書き可)マルチステージビルド
ビルドと実行イメージを分離してサイズ削減
# ===== ステージ1: ビルド =====
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# ===== ステージ2: 本番 =====
FROM node:20-alpine AS production
# セキュリティアップデート
RUN apk update && apk upgrade && apk add --no-cache dumb-init
WORKDIR /app
# ビルド成果物だけをコピー
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
USER node
EXPOSE 3000
# dumb-init: シグナル処理を正しく行う
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "dist/server.js"]
# ===== ステージ3: テスト(オプション)=====
FROM builder AS test
RUN npm testベストプラクティスと .dockerignore
レイヤーキャッシュの最適化とセキュリティ
.dockerignore
# バージョン管理
.git
.gitignore
# 依存関係(コンテナ内でインストール)
node_modules
npm-debug.log
yarn-error.log
# ビルド成果物
dist
build
.next
# 環境設定(機密情報を含む)
.env
.env.local
.env.*.local
# ドキュメント
README.md
docs
# テスト
coverage
__tests__
*.test.ts
# IDE
.vscode
.idea
*.swpレイヤーキャッシュの最適化
FROM node:20-alpine
WORKDIR /app
# ✅ 変更頻度の低いものを先に
# package.json だけコピー → npm install → その後ソースコード
# → package.json が変わらなければ npm install はキャッシュ利用
COPY package*.json ./
RUN npm ci --only=production
# ✅ ここでソースをコピー(npm install と分離)
COPY . .
# ✅ RUN は可能な限り連結してレイヤー数を減らす
RUN apt-get update && apt-get install -y \
curl \
jq \
&& rm -rf /var/lib/apt/lists/* # キャッシュ削除を同じレイヤーで
# ❌ これは3レイヤー生まれて無駄
# RUN apt-get update
# RUN apt-get install -y curl
# RUN rm -rf /var/lib/apt/lists/*