はじめに (対象読者・この記事でわかること)

この記事は、M1/M2チップを搭載したMacBook Air (またはPro) でPHPフレームワークLaravelの開発環境構築に挑戦し、うまく動作せずに困っている方を対象としています。特に、これまでIntel MacやWindowsで開発をしてきて、M1 Macへの移行後に環境構築で躓いた経験がある方には、特にお役に立てる内容かと思います。

この記事を読むことで、M1 Mac特有の互換性問題を理解し、Dockerを利用してLaravel開発環境をスムーズに構築できるようになります。筆者自身がM1 Macでの環境構築で多くの試行錯誤を重ねた経験から、躓きやすいポイントと、その具体的な解決策を分かりやすく解説します。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。 - Dockerの基本的な概念 (コンテナ、イメージなど) - Docker Composeの基本的なコマンド操作 - PHP/Laravelの基本的な概念

M1 MacとPHP/Laravel環境構築の壁:なぜ動かないのか?

M1チップを搭載したMacBook Airが登場した際、その高いパフォーマンスと電力効率に多くの開発者が魅了されました。しかし、従来のIntel製CPU (x86_64アーキテクチャ) とは異なるARMベースのアーキテクチャであるため、既存の開発ツールやライブラリとの互換性の問題が多発しました。

PHPも例外ではありませんでした。M1 Macの登場初期は、PHP本体はもちろん、関連するライブラリや拡張機能、さらにはデータベース (MySQLなど) もARMアーキテクチャに最適化されていないか、あるいはまだ対応が追いついていない状況でした。LaravelはPHPフレームワークであるため、その基盤となるPHP環境が適切に動作しないと、当然ながらLaravelも動きません。

具体的な問題として、以下のような状況が挙げられました。 - HomebrewでインストールされるPHPがIntel版をエミュレーションして動作するため、パフォーマンスが低下したり、特定のエラーが発生したりする。 - Composerでパッケージをインストールする際に、互換性の問題でビルドエラーが発生する。 - MySQLやRedisなどのサービスがARMネイティブに対応しておらず、起動しない、または不安定になる。 - 最終的にLaravelプロジェクト自体は動いても、特定のパッケージがM1環境で動作せず、開発が停止してしまう。

これらの問題を解決し、M1 Mac上で安定したLaravel開発環境を構築するためには、Dockerを利用するのが最も確実で推奨される方法です。Dockerを使うことで、OSのアーキテクチャに依存しない仮想的な開発環境を構築し、ARMアーキテクチャに対応したDockerイメージを選択することで、互換性の問題を吸収することができます。

M1 MacでLaravelを動かす具体的な手順(Docker利用)

ここからは、M1 MacでLaravelを動かすための具体的な手順を、Dockerを利用して解説します。安定した開発環境を構築し、快適なLaravelライフを送りましょう。

ステップ1:開発環境の準備(HomebrewとDocker Desktopのインストール)

まず、M1 Macに必要なツールをインストールします。

  1. Homebrewのインストール ターミナルを開き、以下のコマンドを実行してHomebrewをインストールします。Homebrewは、macOSでソフトウェアを簡単にインストール・管理するためのパッケージマネージャです。M1 Macの場合、ARMアーキテクチャに最適化されたバージョンが自動でインストールされます。

    bash /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" インストールが完了したら、指示に従ってPATHを設定してください。通常は以下のコマンドを実行します。 bash echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile eval "$(/opt/homebrew/bin/brew shellenv)" brew doctor を実行して、問題がないか確認しておきましょう。

  2. Docker Desktop for Mac (Apple Chip版) のインストール Docker Desktopは、DockerをmacOS上で動かすためのアプリケーションです。M1 MacにはApple Chip版をインストールする必要があります。

    • Docker Desktop公式サイト にアクセスし、「Download for Mac (Apple Chip)」を選択してダウンロードします。
    • ダウンロードした.dmgファイルを開き、Docker.appをApplicationsフォルダにドラッグ&ドロップします。
    • ApplicationsフォルダからDockerを起動し、初期設定を行います。初回起動時には、必要なコンポーネントのダウンロードや権限の許可を求められる場合があります。

ステップ2:Laravelプロジェクトの作成とDocker Composeの設定

次に、Laravelプロジェクトを作成し、そのプロジェクトをDockerで動かすための設定を行います。

  1. Laravelインストーラのインストール (Composer経由) Laravelインストーラをグローバルにインストールします。これにより、laravel newコマンドが使えるようになります。 注意: M1 Macのターミナルで直接PHPやComposerを使用する場合、互換性の問題が発生することがあります。しかし、ここではプロジェクト作成時の一時的な利用として割り切ります。最終的にはDockerコンテナ内のComposerを利用します。

    bash composer global require laravel/installer もしcomposerコマンドが見つからない場合は、HomebrewでPHPとComposerをインストールしておきましょう。 bash brew install php composer

  2. 新規Laravelプロジェクトの作成 任意のディレクトリで、新しいLaravelプロジェクトを作成します。 bash laravel new my-laravel-app cd my-laravel-app

  3. Docker Composeファイル (docker-compose.yml) の作成 my-laravel-appディレクトリのルートにdocker-compose.ymlファイルを作成し、以下の内容を記述します。これがDocker環境の核となります。

    ```yaml version: '3.8' services: app: build: context: . dockerfile: Dockerfile container_name: laravel-app ports: - "8000:9000" volumes: - .:/var/www/html depends_on: - mysql - nginx environment: # Laravelの環境変数をここで設定 # 例: APP_ENV, APP_KEY など # .env ファイルがあればそちらが優先されるため、ここでは最低限でOK XDEBUG_MODE: "off" # XDebugが必要な場合は "develop" に変更

    nginx: image: nginx:stable-alpine container_name: laravel-nginx ports: - "80:80" # ホストの80番ポートをコンテナの80番ポートにマッピング volumes: - .:/var/www/html - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - app

    mysql: image: arm64v8/mysql:8.0 # M1 Mac (ARM) 向けに arm64v8 プレフィックスを使用 container_name: laravel-mysql ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: root_password # 適切なパスワードに変更 MYSQL_DATABASE: laravel_db # データベース名 MYSQL_USER: laravel_user # ユーザー名 MYSQL_PASSWORD: laravel_password # ユーザーのパスワード volumes: - dbdata:/var/lib/mysql

    volumes: dbdata: # 永続化のためのボリューム ```

    ポイント: - mysqlサービスのimageには、M1 Mac (ARMアーキテクチャ) に対応したarm64v8/mysql:8.0を指定しています。これにより互換性問題を回避します。 - appサービスは、後述するDockerfileを使ってPHP-FPM環境を構築します。 - volumesでホストとコンテナのファイルを同期させています。特にプロジェクトルート (.) を /var/www/html にマッピングしているため、ホスト側でコードを編集するとコンテナ側にも反映されます。

  4. Dockerfile の作成 my-laravel-appディレクトリのルートにDockerfileを作成します。これはappサービス (PHP-FPM) のコンテナイメージを構築するためのファイルです。

    ```dockerfile FROM arm64v8/php:8.2-fpm-alpine # M1 Mac (ARM) 向けに arm64v8 プレフィックスを使用

    または php:8.2-fpm-alpine でも最近のDocker Desktopは自動でARM版をダウンロードします。

    明示的に arm64v8 を指定することで確実性を高めます。

    WORKDIR /var/www/html

    必要なPHP拡張機能をインストール

    RUN apk add --no-cache \ autoconf \ g++ \ make \ libsodium-dev \ libzip-dev \ jpeg-dev \ png-dev \ freetype-dev \ libwebp-dev \ git \ curl \ openssh-client \ bash \ mysql-client \ icu-dev && \ docker-php-ext-install pdo_mysql opcache bcmath exif gd intl zip sodium && \ docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp && \ docker-php-ext-install -j$(nproc) gd

    Composerをインストール

    COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer

    環境変数 (オプション)

    ENV COMPOSER_ALLOW_SUPERUSER 1 ```

    ポイント: - FROMで指定するPHPイメージも、arm64v8/php:8.2-fpm-alpineのようにARM対応のものを選択します。最近のphp:x.x-fpm-alpineはマルチアーキテクチャ対応が進んでおり、arm64v8をつけなくても自動で適切なものが選択されることが多いですが、明示的に指定することで確実性を高められます。 - 必要なPHP拡張機能 (pdo_mysql, gd, zipなど) をインストールしています。Laravelプロジェクトで不足している場合はここに追加してください。 - Composerを別途インストールしています。これにより、コンテナ内でcomposer installなどのコマンドを実行できます。

  5. Nginxの設定ファイル (default.conf) の作成 my-laravel-appディレクトリの直下にdocker/nginxというフォルダを作成し、その中にdefault.confファイルを作成します。

    ```nginx server { listen 80; server_name localhost; root /var/www/html/public; # Laravelのpublicディレクトリを指定

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
    
    index index.php index.html index.htm;
    
    charset utf-8;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {
        # app サービス (php-fpm) にリクエストを転送
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
    
    location ~ /\.ht {
        deny all;
    }
    

    } `` **ポイント:** -root /var/www/html/public;でLaravelの公開ディレクトリを指定しています。 -fastcgi_pass app:9000;で、app`サービス(PHP-FPMコンテナ)にPHPのリクエストを転送しています。

  6. Laravelの環境設定 (.env) my-laravel-appディレクトリの.envファイルを編集し、データベース接続情報をDocker Composeで設定した内容に合わせます。

    dotenv DB_CONNECTION=mysql DB_HOST=mysql # docker-compose.yml で定義したサービス名 DB_PORT=3306 DB_DATABASE=laravel_db # docker-compose.yml で定義したデータベース名 DB_USERNAME=laravel_user # docker-compose.yml で定義したユーザー名 DB_PASSWORD=laravel_password # docker-compose.yml で定義したパスワード

ステップ3:Docker環境の起動とLaravelの動作確認

すべての設定ファイルが揃ったら、Docker環境を起動してLaravelの動作を確認します。

  1. Dockerコンテナの起動 my-laravel-appディレクトリで、以下のコマンドを実行します。

    bash docker-compose up -d --build - -d: バックグラウンドでコンテナを起動します。 - --build: Dockerfileに変更があった場合に、イメージを再構築します。初回起動時にはイメージのビルドとダウンロードが行われるため、時間がかかることがあります。

    コンテナが正常に起動したか確認するには、docker-compose psコマンドを実行します。 bash docker-compose ps すべてのサービス (app, nginx, mysql) がUpステータスになっていることを確認してください。

  2. Composerパッケージのインストール Laravelプロジェクトの依存関係を解決するために、Composerパッケージをインストールします。このコマンドはappコンテナ内で実行する必要があります。

    bash docker-compose exec app composer install

  3. Laravelの鍵の生成 Laravelアプリケーションのセキュリティキーを生成します。これもappコンテナ内で実行します。

    bash docker-compose exec app php artisan key:generate

  4. データベースマイグレーション(必要であれば) データベースのスキーマを適用します。

    bash docker-compose exec app php artisan migrate

  5. ブラウザでアクセスして確認 ウェブブラウザを開き、http://localhost にアクセスしてください。Laravelのウェルカムページが表示されれば、M1 Mac上でのLaravel開発環境の構築は成功です!

ハマった点やエラー解決

M1 MacでのDockerを使ったLaravel環境構築では、いくつかハマりやすいポイントがあります。

エラー1: Dockerコンテナが起動しない、またはMySQLに接続できない

  • 原因:
    • docker-compose.ymlで指定したDockerイメージがM1 MacのARMアーキテクチャに対応していない。特にMySQLイメージで発生しやすい。
    • .envファイルのデータベース接続情報とdocker-compose.ymlの設定が一致していない。
    • 既にホストOSで同じポート(例: 3306 for MySQL, 80 for Nginx)を使用しているため、ポート競合が発生している。
  • 解決策:
    • docker-compose.ymlのMySQLイメージをarm64v8/mysql:8.0や、Docker Hubで提供されているマルチアーキテクチャ対応の最新バージョン(例: mysql/mysql-server:8.0など)に指定し直す。
    • .envDB_HOSTmysqldocker-compose.ymlのサービス名)になっているか確認し、DB_DATABASE, DB_USERNAME, DB_PASSWORDdocker-compose.ymlenvironmentで設定した値と完全に一致しているか確認する。
    • docker-compose.ymlports設定を調整し、ホストOSで使われていないポートに変更する(例: 3307:3306)。
    • docker-compose logsコマンドで各サービスのログを確認し、起動失敗の原因を特定する。

エラー2: composer installphp artisan コマンドがM1 Macのターミナルで実行できない

  • 原因:
    • M1 Macのローカル環境にインストールされたPHPやComposerが、ARMアーキテクチャ向けに適切にビルドされていない、またはバージョンが古いため。
    • Dockerized環境を構築しているのに、ローカルのPHP環境を使おうとしている。
  • 解決策:
    • すべてのPHP/Composer関連コマンドは、必ずDockerコンテナ内で実行するという原則を徹底する。
      • 例: composer install -> docker-compose exec app composer install
      • 例: php artisan migrate -> docker-compose exec app php artisan migrate
    • ローカルのHomebrewでインストールしたPHPは、極力使用しないようにするか、パスの優先順位を見直す。

エラー3: NginxがPHPファイルを処理しない(502 Bad Gateway)

  • 原因:
    • NginxコンテナがPHP-FPMコンテナ (appサービス) に正常に接続できていない。
    • docker/nginx/default.conf内のfastcgi_passの設定が間違っている。
  • 解決策:
    • default.conf内のfastcgi_pass app:9000;が正しくappサービスを指しているか確認する。
    • appサービス(PHP-FPMコンテナ)が正常に起動しているか、docker-compose psで確認する。
    • docker-compose logs nginxdocker-compose logs app を確認し、エラーメッセージから原因を特定する。

解決策

上記のようなハマりどころを避けるための根本的な解決策は、以下の通りです。

  1. Docker Desktop for Mac (Apple Chip版) の利用: これがM1 Macでの開発の基盤となります。常に最新バージョンを利用し、正しく設定されていることを確認してください。
  2. ARMアーキテクチャ対応のDockerイメージの選択: docker-compose.ymlDockerfileで指定するイメージは、arm64v8プレフィックスが付いているもの、またはDocker Hubでマルチアーキテクチャ対応と明記されているものを選びましょう。これにより、互換性の問題を最小限に抑えられます。
  3. すべてのLaravel/PHP関連操作をDockerコンテナ内で完結させる: M1 Macのローカル環境にPHPやComposerをインストールしても良いですが、原則としてコンテナ内で全ての操作を行うように徹底することで、環境の違いによる問題を回避できます。
  4. 詳細なログの確認: 問題が発生した際は、docker-compose logs [サービス名]コマンドを積極的に利用し、エラーの原因を特定しましょう。

まとめ

本記事では、M1 MacBook AirでLaravel開発環境の構築時に遭遇しがちな互換性の問題と、Dockerを利用した具体的な解決策について解説しました。

  • M1 MacのARMアーキテクチャは、従来のIntelベースのツールとの互換性問題を引き起こす主な原因です。
  • Docker Desktop for Mac (Apple Chip版) と、ARMアーキテクチャに対応したDockerイメージを使用することで、この問題を効率的に解決し、安定した開発環境を構築できます。
  • すべてのPHP/Laravel関連コマンドをDockerコンテナ内で実行する習慣をつけることが、問題回避の鍵となります。

この記事を通して、M1 MacでのLaravel開発環境構築に困っていた方が、スムーズに開発をスタートできるようになることを願っています。Dockerは一度設定してしまえば、プロジェクト間の環境の分離やチーム開発での環境統一にも非常に有効なツールです。

今後は、VS CodeのRemote-Containersを使った開発、Dockerized環境でのXDebugを使ったデバッグ方法、本番環境へのデプロイ方法などについても記事にする予定です。

参考資料