コンテナ

アプリケーションとその依存関係をパッケージ化し、環境に依存しない一貫した実行環境を提供する仮想化技術

コンテナデプロイ

コンテナとは

コンテナは、アプリケーションのコード、ランタイム、ライブラリ、設定ファイルを 1 つのパッケージにまとめ、どの環境でも同一の動作を保証する軽量な仮想化技術である。「自分のマシンでは動くのに本番では動かない」問題を根本的に解決する。

Linux の namespaces (プロセス、ネットワーク、ファイルシステムの分離) と cgroups (CPU、メモリの制限) がコンテナの基盤技術だ。Docker が 2013 年にコンテナを使いやすくパッケージ化し、爆発的に普及した。

VM との違い

観点 コンテナ 仮想マシン (VM)
起動時間 ミリ秒〜秒
サイズ MB 単位 (Alpine: 5MB) GB 単位
カーネル ホスト OS と共有 独自のゲスト OS
分離レベル プロセスレベル ハードウェアレベル
密度 1 ホストに数十〜数百 1 ホストに数個〜数十
適するケース マイクロサービス、CI/CD 強い分離が必要な環境

コンテナはカーネルを共有するため VM より軽量だが、分離レベルは VM より弱い。マルチテナント環境で完全な分離が必要な場合は VM を使う。AWS の Fargate は Firecracker (軽量 VM) 上でコンテナを実行し、両方の利点を組み合わせている。

Dockerfile とイメージの最適化

実務ではイメージサイズの最適化が起動速度とセキュリティの両面で重要だ。

# マルチステージビルドで最終イメージを軽量化
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --production=false
COPY . .
RUN npm run build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
CMD ["node", "dist/index.js"]

最適化のポイント:

  • Alpine ベースイメージを使う (node:20 は 1GB 超、node:20-alpine は 180MB)
  • マルチステージビルドで開発依存を最終イメージに含めない
  • USER node で非 root ユーザーで実行 (セキュリティ)
  • .dockerignore で不要ファイルを除外

1 コンテナ 1 プロセスの原則

1 つのコンテナには 1 つのプロセスだけを実行する。Web サーバーとログ収集エージェントを同じコンテナに入れない。理由は以下のとおり。

  • ヘルスチェックが明確になる (1 プロセスの生死 = コンテナの生死)
  • スケーリングが独立する (Web サーバーだけスケールアウトできる)
  • ログが分離される (stdout に出力すれば、コンテナランタイムが収集)

補助プロセス (ログ収集、プロキシ) はサイドカーパターンで別コンテナとして同一 Pod に配置する。

AWS でのコンテナ実行環境

サービス 特徴 適するケース
ECS on Fargate サーバーレス、インフラ管理不要 小〜中規模、運用負荷を最小化
ECS on EC2 インスタンスを自前管理 GPU、大容量メモリが必要
EKS Kubernetes マネージド K8s エコシステムを活用
Lambda (コンテナイメージ) イベント駆動、最大 10GB 既存コンテナを Lambda で実行

Lambda もコンテナイメージをサポートしている。既存の Docker イメージを Lambda で実行でき、最大 10GB のイメージサイズに対応する。

よくある失敗パターン

イメージに機密情報を含める

Dockerfile の ENVCOPY で API キーやパスワードをイメージに焼き込むと、イメージを取得した誰もが機密情報にアクセスできる。機密情報は環境変数や Secrets Manager で実行時に注入する。

latest タグの使用

FROM node:latest は再現性がない。ビルドのたびに異なるバージョンが使われる可能性がある。必ずバージョンを固定する (FROM node:20.11-alpine)。

# マルチステージビルド
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:22-alpine
COPY --from=build /app/dist ./dist
CMD ["node", "dist/index.js"]

詳しくは関連書籍を参照。

関連用語