🐡

M2 MacBookでのDocker環境構築:ReactとPostgreSQLを使った環境で発生したトラブルとその解決法

2024/11/09に公開

環境情報

  • デバイス: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にインストールされたesbuildrollupなどのプラットフォーム依存のバイナリが原因です。

2. 解決方法

解決手順1:docker-compose.ymlのボリューム設定

ローカルの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環境向けにインストールされたもののみを使用するようにしました。

解決手順2:Viteの設定ファイル修正

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.jsonpackage-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.jsonpackage-lock.jsonを先にコピーすることで、依存関係が変更されない限りキャッシュが利用され、ビルドが高速化されます。

結果

これらの設定を反映した後、Dockerコンテナ内でReactとPostgreSQLの環境が正常に起動し、ローカルの変更もホットリロードで即時反映されるようになりました。

まとめ

M2 MacBookでDockerを使用してReactとPostgreSQLの環境構築を行う際には、プラットフォーム依存の問題に注意が必要です。特にnode_modulesの管理を適切に行い、Docker内部での依存関係をコンテナ内で完結させることで、ARMアーキテクチャに起因するエラーを回避できます。

これらの対応により、効率的で安定した開発環境を構築することができました。M1/M2チップ搭載のMacで同様の構築を検討している方には、同様の手順をお勧めします。

Discussion