M2 MacBookでのDocker環境構築:ReactとPostgreSQLを使った環境で発生したトラブルとその解決法
環境情報
- デバイス:MacBook Air (M2, 2022)
- メモリ:8 GB
- OS:macOS Sonoma 14.5
- プロジェクト概要:Dockerを使用してReact(Vite)とPostgreSQLの開発環境を構築
フォルダ構成
project-root/
├── frontend/
├── backend/
├── docker/
│ ├── frontend/
│ ├── backend/
│ └── db/
└── docker-compose.yml
背景
M2チップを搭載したMacでは、ARMアーキテクチャによるプラットフォーム依存の問題が発生することが多々あります。特に、Dockerコンテナ内でLinux(x86_64アーキテクチャ)向けのバイナリを扱う際に、プラットフォームの違いからエラーが起きるケースがあります。
1. エラー内容と原因
Dockerでフロントエンド(React)を立ち上げる際、以下のエラーが発生しました。
エラーメッセージ
- Cannot find module @rollup/rollup-linux-arm64-musl
-
esbuildバイナリのプラットフォーム依存問題(
@esbuild/darwin-arm64
がインストールされているが、@esbuild/linux-x64
が必要)
これらのエラーは、ARMベースのMac(M2)上でインストールされた依存パッケージの一部が、DockerコンテナのLinux環境で動作しないために発生しました。特に、node_modules
にインストールされたesbuild
やrollup
などのプラットフォーム依存のバイナリが原因です。
2. 解決方法
docker-compose.yml
のボリューム設定
解決手順1:ローカルのnode_modules
ディレクトリがDockerコンテナにマウントされていると、プラットフォームの違いにより依存関係の不整合が発生します。そのため、docker-compose.yml
のボリューム設定を以下のように修正しました。
frontend:
container_name: frontend-app
build:
context: .
dockerfile: docker/frontend/Dockerfile
platform: linux/amd64 # x64アーキテクチャをエミュレート
ports:
- "3000:3000"
volumes:
- ./frontend:/app # ソースコードをコンテナにマウント
- /app/node_modules # `node_modules`をコンテナ内でのみ管理
networks:
- app-network
-
/app/node_modules
をコンテナ内部でのみ管理:この設定により、ホスト環境(macOS)のnode_modules
をコンテナ内で使用せず、Linux環境向けにインストールされたもののみを使用するようにしました。
Vite
の設定ファイル修正
解決手順2:Docker環境では、ファイルの変更をポーリングで監視する設定が必要です。また、コンテナ外部からアクセスするため、Viteの設定ファイルvite.config.ts
に以下の設定を追加しました。
import { defineConfig } from 'vite';
export default defineConfig({
server: {
host: '0.0.0.0', // 外部からのアクセスを許可
watch: {
usePolling: true, // ポーリングでファイル変更を検知
},
},
});
-
usePolling: true
:ホットリロードがDocker環境で正しく機能するようになります。 -
host: '0.0.0.0'
:コンテナ外からのアクセスを許可する設定です。
3. 最終的なDockerfileの設定
さらに、Dockerfileの改善も行いました。具体的には、キャッシュを効率的に使うために、package.json
とpackage-lock.json
のみを先にコピーしてnpm install
を実行し、その後でプロジェクト全体をコピーするようにしました。
# ベースイメージの指定
FROM node:22-alpine
# 作業ディレクトリの設定
WORKDIR /app
# package.jsonのみ先にコピーし、依存関係をインストール
COPY ./frontend/package*.json ./
RUN npm install
# プロジェクトのソースコードをコピー
COPY ./frontend .
# サーバーのポートを公開
EXPOSE 3000
# Viteサーバーを起動
CMD ["npm", "run", "dev"]
-
キャッシュの利用:
package.json
とpackage-lock.json
を先にコピーすることで、依存関係が変更されない限りキャッシュが利用され、ビルドが高速化されます。
結果
これらの設定を反映した後、Dockerコンテナ内でReactとPostgreSQLの環境が正常に起動し、ローカルの変更もホットリロードで即時反映されるようになりました。
まとめ
M2 MacBookでDockerを使用してReactとPostgreSQLの環境構築を行う際には、プラットフォーム依存の問題に注意が必要です。特にnode_modules
の管理を適切に行い、Docker内部での依存関係をコンテナ内で完結させることで、ARMアーキテクチャに起因するエラーを回避できます。
これらの対応により、効率的で安定した開発環境を構築することができました。M1/M2チップ搭載のMacで同様の構築を検討している方には、同様の手順をお勧めします。
Discussion