docker環境にあるCakePHPプロジェクトを高速化する
もはや開発環境にdockerを使用している人(会社)も多いと思います。
しかし、dockerにCakePHPのプロジェクトをマウントした場合、ものすごい重くなるかと思います。
今回は弊社で対応した内容をご紹介します。
そもそもなんで重たいのか?
docker内のコンテナとファイルを共有する volume はマウントという形で構成しています。
この時、プロジェクトをマウントしている場合、すべてのファイルへのアクセスが可能になりますが、逆にファイルI/Oが発生することを意味します。
CakePHPでは vendor ディレクトリ内にCakePHP本体を含むライブラリ群が入っており、そのファイル数は膨大なものになっています。
これらのファイルへのアクセスが結果といて処理を遅くしている大きなポイントの1つです。
どのように高速化するのか
結論から先に言うと vendorディレクトリをコンテナ内に配置する です。
具体的な方法ですが、まずは docker-compose.yml を編集します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
version: '3' services: nginx: container_name: nginx build: context: ./nginx dockerfile: Dockerfile ports: - "80:80" - "443:443" network_mode: bridge volumes: - ../bin:/var/www/html/bin - ../config:/var/www/html/config - ../logs:/var/www/html/logs - ../plugins:/var/www/html/plugins - ../src:/var/www/html/src - ../templates:/var/www/html/templates - ../tests:/var/www/html/tests - ../tmp:/var/www/html/tmp - ../webroot:/var/www/html/webroot php: container_name: php build: context: ./php dockerfile: Dockerfile ports: - "9000:9000" volumes: - ../bin:/var/www/html/bin - ../config:/var/www/html/config - ../logs:/var/www/html/logs - ../plugins:/var/www/html/plugins - ../src:/var/www/html/src - ../templates:/var/www/html/templates - ../tests:/var/www/html/tests - ../tmp:/var/www/html/tmp - ../webroot:/var/www/html/webroot |
まずは volumes に vendor ディレクトリを設定します。
そして Dockerfile を編集します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
FROM nginx:1.18.0 RUN apt-get update && apt-get install -y \ apt-utils \ vim \ locales \ iproute2 \ iputils-ping \ net-tools \ && echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen \ && locale-gen ja_JP.UTF-8 \ && mkdir -p /var/www/html/vendor/ COPY ./vendor/ /var/www/html/vendor/ ENV LC_ALL ja_JP.UTF-8 |
これでイメージ作成時に vendor ディレクトリがコピーする処理が追加されました。
最後に vendor ディレクトリをコピー します。
これは Dockerfileの制限 が問題になっています。
Dockerfile は シンボリックリンク(およびリンク)をたどってコピーできない & Dockerfileより上に遡れない ためです。
今回の構成は CakePHPプロジェクト内に docker ディレクトリがあり、その中に各サーバーの設定が入っているため、Dockerfileよりvendorディレクトリが上の階層にいます。
なので Dockerfile と同じ階層に vendor ディレクトリをコピーする必要があるわけです。
ここまで来たら後は簡単、 docker-compose を実行しましょう。
1 2 3 |
$ docker-compose up -d |
これでアクセス速度が爆速になります。
tmpなどのキャッシュもI/Oが激しいディレクトリの1つですので、入れておいても良いかもしれません
デメリットもある
コンテナ内に vendor ディレクトリごとコピーすることで高速化できましたが、その結果としてデメリットも発生します。
- コピーした内容を更新・削除する時に手間がかかる
- Gitで共有しづらい
マウントしているわけではないので、当然 composer で更新した vendor ディレクトリ内は自動で更新されません。
これは docker コマンドのディレクトリコピーで更新することができます。
ただ、これも問題があり、vendor や node_module などのライブラリを格納するディレクトリは、中身をgitに入れないようにするのが普通です。
そのため、ライブラリを更新した際に他の開発者へ更新した旨を伝え、各人がライブラリを更新するコマンドを実行する必要があります。
docker-compose.yml の command で毎回更新してもよいのですが、各人で composer.lock ファイルが更新され、場合によっては地獄を見ます。
この辺も自動化できれば良いのですが・・・。
さいごに
この解決に至るまでかなり時間を要しました。
ただ、これのおかげで Vue.js や Node.js なども高速化することができることがわかったので、時間をかけた甲斐がありました。
この記事を見た人が少しでも解決することを願います。
ではでは。
- おすすめ記事
-
-
のえる2020.07.23
-
CakePHPでVue.jsを利用する方法
のえる2021.01.12 -
ngrokで開発環境をそのまま外向けに公開する
のえる2020.03.25
-
POPULAR
のえる
Full-stack Developer