複数人の開発メンバーや異なるOS(macOS, Windows, Linux)が混在するプロジェクトにおいて、開発環境の差異による「自分のマシンでは動くが、他人のマシンでは動かない」という問題は頻繁に発生します。Docker Composeは、こうした開発環境の共通化に非常に有効なツールですが、適切な設計を行わないと、コンテナの起動速度低下、パーミッション問題、環境変数の漏洩などの課題に直面します。
この記事では、実務でそのまま活用できるDocker Composeの設定例、マルチプラットフォーム対応の注意点、および本番環境との差異を管理するための構成パターンを解説します。
対象読者
- プロジェクトでDocker Composeを用いた開発環境の構築・共通化を担当するエンジニア
- メンバー間で開発環境の動作差異を減らしたいチームリーダー
- macOS(Apple Silicon含む)とWindows(WSL2)が混在する環境でDockerを運用している方
1. 実務で使えるDocker Compose構成テンプレート
以下は、Webアプリケーション(Node.js)とデータベース(PostgreSQL)を組み合わせた、開発環境向けの標準的な docker-compose.yml の構成例です。
services:
web:
build:
context: .
dockerfile: Dockerfile.dev
image: myapp-web:dev
container_name: myapp-web-dev
ports:
- "3000:3000"
volumes:
- .:/app:cached
- /app/node_modules
environment:
- NODE_ENV=development
- DATABASE_URL=postgres://postgres:postgres_password@db:5432/myapp_dev
env_file:
- .env.local
depends_on:
db:
condition: service_healthy
db:
image: postgres:15-alpine
container_name: myapp-db-dev
ports:
- "5432:5432"
volumes:
- db-data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres_password
- POSTGRES_DB=myapp_dev
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
volumes:
db-data:
設定のポイント
-
匿名ボリュームによる
node_modulesの保護
- /app/node_modulesという記述により、ホスト側のnode_modulesがコンテナ内にマウントされて上書きされるのを防ぎます。これにより、ホストOSとコンテナOS(Linux)の間でネイティブモジュールの不整合が発生するのを回避します。 -
cachedフラグの利用(macOS対策)
- .:/app:cachedのようにcached一貫性フラグを指定することで、macOS上のDocker Desktopにおけるファイルシステム同期のパフォーマンスを向上させます。 -
depends_onとhealthcheckによる起動順制御
単にdepends_onにサービス名を指定するだけでは、データベースのプロセスが完全に起動して接続を受け付ける前にWebアプリケーションが起動し、接続エラーになることがあります。service_healthy条件を組み合わせることで、データベースの準備が整ってからWebアプリケーションを起動させます。
2. 開発環境共通化における注意点と対策
① OS間のパーミッション(権限)差異
LinuxホストとmacOS/Windowsでは、バインドマウントしたファイルの権限の扱いが異なります。Linux環境では、コンテナ内で作成されたファイルの所有者が root になり、ホスト側で編集できなくなる問題が発生しがちです。
対策:
Dockerfile内で非ルートユーザーを作成し、コンテナ実行時のUID/GIDをホストと一致させるか、以下のように docker-compose.yml で実行ユーザーを指定できるようにします。
services:
web:
user: "${CURRENT_UID:-1000}:${CURRENT_GID:-1000}"
起動前にホスト側で環境変数を設定します。
export CURRENT_UID=$(id -u)
export CURRENT_GID=$(id -g)
docker compose up
② Apple Silicon (M1/M2/M3) への対応
ARMアーキテクチャのMacと、x86_64アーキテクチャのWindows/Linuxが混在する場合、一部のイメージが動作しない、またはエミュレーション(Rosetta 2)により極端に動作が遅くなることがあります。
対策:
可能な限りマルチプラットフォーム対応の公式イメージ(Alpineベースなど)を使用してください。どうしても特定のアーキテクチャ用イメージが必要な場合は、platform を明示的に指定します。
services:
db:
image: mysql:8.0
platform: linux/amd64
※ただし、エミュレーションによる実行はパフォーマンス低下を伴うため、最新の公式ドキュメントを確認し、ネイティブARMイメージが提供されている場合はそちらを優先してください。
③ 環境変数の管理ルール
.env ファイルにAPIキーやパスワードなどの機密情報を直接記述し、Gitリポジトリにコミットしてしまう事故が後を絶ちません。
対策:
-
.envはGit管理から除外(.gitignoreに追加)します。 - 代わりに、設定項目の雛形を示した
.env.exampleをリポジトリにコミットします。 - 開発者は
.env.exampleを.envにコピーし、ローカル用の値を設定して利用します。
3. 開発環境共通化チェックリスト
プロジェクトにDocker Composeを導入・配布する前に、以下の項目を満たしているか確認してください。
| チェック項目 | 確認内容 | 判定基準 |
|---|---|---|
| ポータビリティ | ホスト固有の絶対パス(/Users/username/...など)が記述されていないか |
相対パス(./)のみで構成されていること |
| ポート競合防止 | ホスト側ポートが他のプロジェクトと重複していないか | 必要に応じて環境変数でポートを変更可能にしていること |
| データ永続化 | コンテナを破棄(docker compose down -v)しても必要なデータが消えないか |
データベース等のデータがNamed Volumeに保存されていること |
| 不要ファイルの除外 | ホスト側のキャッシュやログがコンテナに同期されていないか |
.dockerignore が適切に設定されていること |
| ドキュメント化 | 起動手順やトラブルシューティングが明記されているか |
README.md に docker compose up までの手順があること |
まとめ
Docker Composeを用いた開発環境の共通化は、チーム全体の生産性を向上させる強力な手段です。しかし、OSごとのファイルシステム特性やアーキテクチャの違い、セキュリティへの配慮を怠ると、かえってトラブルシューティングに時間を取られる原因になります。
本記事で紹介したテンプレートやチェックリストをベースに、プロジェクトの要件に合わせてカスタマイズし、堅牢で使いやすい開発環境を構築してください。
※DockerやDocker Composeの仕様はアップデートにより変更される場合があります。導入の際は、必ず最新のDocker公式ドキュメントを併せてご確認ください。