DockerでLaravel動かす時に処理が重い問題の対処法

どうもLhaplus(ラプラス)です。

今回はDockerで仮想環境構築していて、Laravel動かしている時に処理が重たくなる問題について解決したので記事として記録しておきます。

コンテナ構築時に、ディレクトリーのマウントをしない場合は動作が重くなることはないのですが、普通はVS Codeとかでコード編集すると思うので、マウント環境は設定すると思います。

その場合の対処法を記します。

私の環境
  • Windows 10 Pro 64bit
  • Docker Desktop 19.03.12
  • Docker-compose 1.27.2

処理が重たくなる原因

Laravel開発するときには、おそらくコンテナ起動するときには、

docker run -v '[マウント元ディレクトリーパス]:/var/www/html' -itd -p 80:80 -p 443:443 --privileged [コンテナ] /sbin/init

こんな感じで起動させることが多いかもしれません。この例では、マウント元とマウント先「/var/www/html」でLaravelのプロジェクト領域全体を含める形にしています。

Laravelのプロジェクトディレクトリープロジェクトディレクトリー全体をマウントしてしまうのが手っ取り早いですが、これだとブラウザーでサイトにアクセスするたびに読み込みで待たされストレスが貯まります。

自分の場合だと、ページ遷移するたびに15秒以上かかってました。

なんでこんなに時間がかかってしまうのか色々調べた結果、Laravelが動作する毎に大量のファイルやデータが読み込み・書き込み・削除の処理に追われ、マウント元の同期に時間がかかることでした。

じゃあどの場所でそんな大量の処理をしているかというと、Laravelプロジェクトディレクトリ直下にある、「storage」が問題の場所でした。「storage」ディレクトリでは、LaravelのコンパイルされたBladeテンプレート、セッション情報、ファイルキャッシュ、ログなどのデータがアクセスするごとに処理するようになっているようで、一番の重い原因となっていました。その他にも、「bootstrap」ディレクトリではサイトキャッシュの制御も行われているので、これも重い原因になっているように想います。

なので、対処法としては「storage」と「bootstrap」以外のディレクトリをマウントすれば解決できます。

私の対処方法

上記の問題点を含めて考えると、「ファイルの生成と削除を大量に伴うディレクトリはマウントしないようにする」ことで極端に重くなることはなくなります。

マウントの設定をするときは少し手間になりますが、個別にディレクトリを指定するようにします。

「docker run」コマンドでも「-v」オプションの複数記載で実行もできますが、かなり長くなって扱いが面倒になるので、ここからは「docker-compose」を使ってコンテナを構築します。

docker-composeをまだ導入していない場合は、

[Docker] Windows 10 Pro 64bit に Docker と Docker Compose をインストールする

で導入方法を開設しているので参考にしてみてください。

そしたら、まず「docker-compose.yml」ファイルを作成して、以下のように内容を記載します。

version: '2'
services:

  bildrop: # 任意のサービス名
    image: laravel-image:1.0 # 使用するイメージ
    container_name: bildrop_latest # コンテナ名
    #restart: always # 常にコンテナを起動状態にするか
    ports: # HTTP通信用のポートを開放
      - 80:80
      - 443:443
    cap_add:
      - SYS_ADMIN
    security_opt:
      - seccomp:unconfined
    privileged: true
    command: /sbin/init
    volumes: # マウントの設定
      - ./source/app:/var/www/html/app
      - ./source/config:/var/www/html/config
      - ./source/database:/var/www/html/database
      - ./source/public:/var/www/html/public
      - ./source/resources:/var/www/html/resources
      - ./source/routes:/var/www/html/routes

マウント元のディレクトリ構成は以下のようになります。

......
|-- docker-compose.yml
|-- source
  |-- app
  |-- config
  |-- database
  |-- public
  |-- resources
  |-- routes

手順としては、まずマウント元の「source」ディレクトリに上記で示したリストの空ディレクトリを作っておきます。その後、起動したコンテナにアタッチして、「/var/www/html」内で、Laravelプロジェクト一式をGitHubの自分のリポジトリからクローンしてあげれば完了です。

実際にこの環境で、処理速度を測ってみると、1秒もかからなくなりました。とりあえず、これで快適に開発ができますね。

補足

今回の方法を試す前に、最近利用している方も多い「docker-sync」も試してみましたが、最後の最後でうまく動作させることができず、利用を諦めました。まだ比較的新しい技術みたいなので、色々と改良は必要だと想います。途中まで使ってみた感想は、Laravelのプロジェクトディレクトリ全体をマウントさせた状態でも、動作に1秒もかかっていない感じの爆速ぶりでした。

試しにこっちを最初に使ってみるのがいいかもしれません!!

Docker-sync ドキュメント(英語のみ)

おすすめの記事