導入
開発を始めるたびに「Node.jsのバージョンが違う」「PostgreSQLのインストールに失敗する」「Macでは動くのにWindowsでは動かない」といったトラブルに直面したことはありませんか。こうした「環境差異」の悩みを根本から解決するのがDockerです。とはいえ、非エンジニアにとってDockerfileやdocker-compose.ymlの記述はハードルが高いのも事実。そこで活躍するのがClaudeCodeです。プロジェクトの要件を自然言語で伝えるだけで、適切なDockerfileやcompose設定を生成してくれます。本記事では、Dockerの基礎からClaudeCodeを使った実践的な活用法、本番運用に耐えるベストプラクティスまでを8,000字以上のボリュームで解説します。
結論
結論からお伝えすると、ClaudeCodeにDocker関連ファイルの作成を任せることで、コンテナ開発のハードルは一気に下がります。具体的には、Dockerfileの生成、docker-compose.ymlの構成、.dockerignoreの作成、マルチステージビルドの最適化、開発用と本番用の使い分け、Volumeとネットワークの設定までを、すべて自然言語で依頼できます。重要なポイントは三つです。第一に、プロジェクトの言語・フレームワーク・依存サービスを明確に伝えること。第二に、「開発用か本番用か」を区別して依頼すること。第三に、生成されたファイルの中身を読み、Volumeマウントや環境変数の扱いを必ず確認すること。なお、社内ルールに従ってインターネット公開アプリのホスティングはCloudflare Workersが基本となるため、Dockerは「ローカル開発環境」と「データベース・補助サービスの起動」を中心に使うのが正解です。本番のWeb配信用途でDockerを使う場合はエンジニアへの相談をおすすめします。
Dockerとは何か?基礎からやさしく解説
Dockerは、アプリケーションを「コンテナ」と呼ばれる軽量な仮想環境にパッケージする技術です。コンテナの中には、OSのファイル群、ランタイム(Node.jsやPythonなど)、ライブラリ、アプリ本体がすべて含まれており、「動くマシンの状態」をまるごと持ち運べる箱だと考えると分かりやすいでしょう。
従来の仮想マシン(VirtualBoxやVMwareなど)はOSごと丸ごと仮想化するため重たく、起動に数分かかりました。Dockerはホストマシンのカーネルを共有することで、秒単位で起動できる軽さを実現しています。これにより、開発・テスト・本番のすべての段階で「同じ環境」を再現できるようになりました。
Dockerには三つの主要概念があります。「イメージ」は環境のテンプレート、「コンテナ」はイメージを起動した実体、「Dockerfile」はイメージを作るためのレシピです。さらに、複数のコンテナをまとめて管理するための仕組みが「docker-compose」で、Webアプリ・データベース・キャッシュサーバーを同時に起動するときに重宝します。
ClaudeCodeでDockerをインストール・初期化する
まずはDockerをインストールしましょう。macOSとWindowsでは「Docker Desktop」を公式サイトからダウンロードしてインストールするのが標準です。インストール後、ターミナルでdocker --versionが表示されれば準備完了です。
次にプロジェクトにDocker環境を導入します。ClaudeCodeに次のように依頼します。
このNext.jsプロジェクトをDocker化したいです。開発用のDockerfileとdocker-compose.ymlを作成してください。Node.js 20、ホットリロード対応、PostgreSQLとRedisを別コンテナで起動できるようにしてください。
ClaudeCodeは以下を行います。
package.jsonを読んで依存関係を把握- 適切なベースイメージ(例:
node:20-alpine)を選択 Dockerfile、docker-compose.yml、.dockerignoreを生成
Dockerfileの基本構造とClaudeCodeでの生成
Dockerfileは、コンテナイメージの作り方を一行ずつ記述するファイルです。代表的な命令にはFROM、WORKDIR、COPY、RUN、EXPOSE、CMDがあります。
ClaudeCodeが生成する開発用Dockerfileの例です。
# 開発用Dockerfile
FROM node:20-alpine
WORKDIR /app
# 依存関係のインストール(キャッシュ効率化のため先にコピー)
COPY package.json package-lock.json ./
RUN npm ci
# ソースコードをコピー
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]
本番用は、サイズと起動速度を意識して「マルチステージビルド」を使うのが定石です。ClaudeCodeに以下のように依頼します。
本番デプロイ用のDockerfileを、マルチステージビルドで作成してください。最終イメージは可能な限り小さくしてください。
出力例は次のとおりです。
# マルチステージビルド:本番用Dockerfile
# Stage 1: ビルドステージ
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: 実行ステージ
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
# 必要なファイルだけをbuilderからコピー
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
USER node
CMD ["npm", "start"]
これだけで、開発時のイメージは1GB前後でも、本番イメージは200-300MB程度まで圧縮できます。
docker-compose.ymlで複数サービスを束ねる
実際のWebアプリは「アプリ本体+データベース+Redis+メール送信モック」のように複数のサービスで構成されます。これらを一括起動するのがdocker-compose.ymlです。
ClaudeCodeへの依頼例。
Next.jsアプリ、PostgreSQL 16、Redis 7、メール確認用のMailHogをdocker-composeで束ねてください。データベースとRedisのデータはボリュームで永続化してください。環境変数は.envファイルから読み込めるようにしてください。
生成例は次のとおりです。
version: '3.9'
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- .:/app
- /app/node_modules
environment:
DATABASE_URL: postgres://postgres:postgres@db:5432/myapp
REDIS_URL: redis://redis:6379
env_file:
- .env
depends_on:
- db
- redis
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: myapp
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
- redis_data:/data
ports:
- "6379:6379"
mailhog:
image: mailhog/mailhog
ports:
- "1025:1025" # SMTP
- "8025:8025" # Web UI
volumes:
postgres_data:
redis_data:
これをdocker compose upで起動すれば、開発に必要な環境が一気に揃います。
.dockerignoreの重要性
.dockerignoreは、COPY命令でコンテナに含めたくないファイルを指定するためのファイルです。これを書かないと、node_modulesや.git、.envまで丸ごとイメージに含まれてしまい、サイズが膨らみ、セキュリティ事故も起きやすくなります。
ClaudeCodeに依頼すれば一発で適切な内容を生成してくれます。
このNext.jsプロジェクトの.dockerignoreを作成してください。秘密情報やビルド成果物が誤って含まれないようにしてください。
出力例:
node_modules
.next
.git
.gitignore
.env
.env.local
.env.*.local
*.log
.DS_Store
README.md
coverage
.vscode
.idea
Dockerfile*
docker-compose*.yml
特に.env系を含めないことは絶対条件です。APIキーやDB接続情報がイメージに焼き込まれると、Docker Hubなどに公開した瞬間に情報漏洩につながります。
ボリュームマウントとホットリロード
開発時にコードを編集するたびにイメージを作り直すのは非効率です。そこで「ボリュームマウント」を使い、ホストのコードをコンテナにリアルタイム反映させます。先ほどのdocker-compose.ymlで書いた
volumes:
- .:/app
- /app/node_modules
の二行がポイントです。一行目で現在のディレクトリをコンテナの/appにマウントし、二行目でコンテナ内のnode_modulesがホストに上書きされるのを防いでいます。これにより、コードを保存すれば即座にNext.jsがホットリロードしてくれます。
データベース移行・シードデータの扱い
Prismaを使っている場合、コンテナ内でマイグレーションを走らせるには次のコマンドを使います。
docker compose exec app npx prisma migrate dev
docker compose exec app npx prisma db seed
ClaudeCodeに以下のように依頼すれば、Prismaのマイグレーションを自動で行うエントリーポイントスクリプトも作成してくれます。
コンテナ起動時に自動でPrismaのマイグレーションが走るように、entrypoint.shを作成してDockerfileに組み込んでください。
トラブルシューティング:よくあるエラー
Dockerでよく遭遇するエラーをClaudeCodeに丸投げできるのも嬉しい点です。
docker compose upを実行すると以下のエラーが出ます。原因と修正方法を教えてください。
(ここにエラーメッセージを貼り付け)
代表的なものを挙げておきます。
bind: address already in use→ ポートが他のプロセスと衝突しているので、portsの左側を変更permission denied→ ファイル所有者の問題、USER命令かchownで対処no space left on device→docker system prune -aで不要なイメージを削除
ベストプラクティス
開発を続けるなかで意識したいベストプラクティスをまとめます。
- ベースイメージは公式のalpine版を選ぶ:軽量で攻撃面が小さい
- マルチステージビルドを使う:本番イメージのサイズを最小化
.dockerignoreを必ず書く:機密情報の混入を防ぐUSER命令でrootを避ける:セキュリティリスクを下げるHEALTHCHECKを設定:コンテナの異常を自動検知- イメージタグを固定:
latestではなくnode:20.11-alpineのように具体的に - 環境変数はDockerfileに書かず
env_fileかsecretsで渡す:APIキーをイメージに焼き付けない
特に最後の点は社内ルールでも厳しく守るべき箇所です。Cloudflare Workersにデプロイする本番アプリでも、APIキー・パスワード・トークンは必ずCloudflare SecretsかWorkers Secretsに保存し、ソースコードやDockerイメージに書き込んではいけません。
実践チュートリアル:実プロンプト例集
プロンプト例1:プロジェクト全体のDocker化
既存のNode.js + Expressプロジェクトを、開発用と本番用のDockerfileに分けてDocker化してください。docker-compose.ymlも併せて作成し、PostgreSQLを同時に立ち上げられるようにしてください。
プロンプト例2:Pythonプロジェクトのコンテナ化
FastAPIで作ったAPIサーバーをDocker化したいです。Python 3.12、Poetryで依存管理、本番用はGunicornで起動するようにしてください。
プロンプト例3:開発用と本番用の使い分け
docker-compose.dev.ymlとdocker-compose.prod.ymlを分けて作成してください。dev側はホットリロードとデバッガ接続を有効に、prod側はマルチステージビルド済みイメージを使うように設定してください。
プロンプト例4:イメージサイズの最適化
現在のDockerfileでビルドされるイメージが800MBあります。マルチステージビルドと不要パッケージの削除で300MB以下に縮めてください。
プロンプト例5:CI/CDでのイメージビルド
GitHub Actionsで、mainブランチへのプッシュ時にDockerイメージをビルドしてGitHub Container Registryにpushするワークフローを作成してください。タグはコミットSHAと"latest"の両方を付けてください。
プロンプト例6:依存サービスの統合
docker-compose.ymlに、メール送信検証用のMailHog、S3互換ストレージのMinIO、ログ集約のGrafana Lokiを追加してください。
FAQ
Q1. Docker DesktopとDocker Engineの違いは何ですか? Docker DesktopはmacOS/Windows向けのGUIアプリで、内部的にLinux VMを動かしてDocker Engineをホストしています。Linuxサーバーでは直接Docker Engineを使うため、Desktop版は不要です。社内開発ではDocker Desktopで十分です。
Q2. ファイル変更が反映されません。何が原因?
ボリュームマウントが正しく設定されていない可能性が高いです。docker-compose.ymlのvolumes設定を見直し、ホットリロード対応のフレームワーク(Next.jsならdevサーバー)が起動しているか確認してください。Windowsの場合はファイル監視がうまく効かないことがあるため、CHOKIDAR_USEPOLLING=trueを環境変数で渡すと改善することがあります。
Q3. コンテナ内に入って操作するにはどうすればいい?
docker compose exec app shまたはbashでシェルに入れます。データベースの中身を確認したいときはdocker compose exec db psql -U postgres myappのように使います。
Q4. ディスク容量を圧迫しています。どうすれば?
docker system prune -a --volumesで未使用のイメージ・コンテナ・ボリュームを一括削除できます。定期的に実行する習慣をつけましょう。
Q5. Cloudflare WorkersにDockerは使えますか? Cloudflare Workersは独自のV8 Isolate環境で動くため、Dockerは使いません。Dockerはあくまでローカル開発環境やDB起動用と割り切り、本番ホスティングはWorkersに任せるのが社内推奨構成です。
Q6. 秘密情報をどう渡すのが安全?
.envファイルをenv_fileで読み込ませる方法が手軽ですが、本番ではDocker Secretsか、Cloudflare Secretsのような外部のシークレット管理サービスを使ってください。DockerfileのENV命令に直接書くのは絶対NGです。
Q7. M1/M2 Macでplatformエラーが出ます。
ARM64向けでないイメージを使うとエラーになります。docker-compose.ymlの該当サービスにplatform: linux/amd64を追加するか、ARM対応イメージに切り替えてください。
まとめ
本記事ではDockerの基本から、ClaudeCodeを使ったDockerfile・docker-compose.ymlの自動生成、ボリューム・ネットワーク・シークレットの扱い、そしてベストプラクティスまでを一気通貫で解説しました。重要なのは、Dockerは「正しい構成」を一度作ってしまえば、誰でも同じ環境を再現できる魔法のような仕組みであるということです。ClaudeCodeに自然言語で依頼すれば、その「正しい構成」を最短経路で手に入れられます。社内ルール上、本番Web公開はCloudflare Workersが原則ですので、Dockerは「ローカル開発の安定化」と「補助サービスの起動」に活用していきましょう。秘密情報の扱いだけは絶対に妥協せず、安全な開発基盤を整えてください。