TL;DR
- Docker for mac でローカルのボリュームをマウントすると非常に動作が遅い
- 解決策として、頻繁に更新されるものだけをボリュームとしてマウントし、それ以外はDockerイメージ内に入れてしまう
- 副作用としては、上記でマウントしたボリューム外のファイルを更新するのがすこしだけ厄介
- ただし、それは別途マウントすればいいだけなので、そこまで大きな問題ではない
経緯
WordPressの開発環境(PHP,MySQL)をホストOS直下に入れたくなかったし、Gitリポジトリにコードの形で残しておきたかったので、Dockerで開発出来るようにしていた。 以前使っていたのは https://phpdocker.io/ の docker-compose.yml
および Dockerfile 系の一式
しかし、PHPの様々なスクリプトファイルを読み出す処理とDocker for macのvolumesでホストOS側のディレクトリをマウントする仕組みの相性が悪く困っていたので、解決した。
原因であるDocker for macのvolumesが遅い問題はこの辺の記事がわかりやすいかと https://blog.hanhans.net/2017/05/23/docker-for-mac-slow/
cachedを使えば良いnかもしれないけれど、この記事では別な方針で解決している。
方法と実際のコード
TL;DR
に書いた通りで、頻繁に更新されるファイルだけをボリュームとしてマウントすればいいし、それ以外はDockerイメージに入れてしまえばここまで遅くならない。
私が開発している案件ではWordPress本体コードも全てGitリポジトリ以下に置いている(※ただしwp-config.php等は本番サーバーとは異なるものがリポジトリに入っている)が、すこしだけ変えればテーマのみをリポジトリで管理しているような案件でも使えるはず。
version: "3.1"
services:
wordpress:
build: .
volumes:
# theme以下はbuild時だけでなく更新かけたいのでVOLUMEで入れてる
- ./wordpress/wp-content/themes/mytheme:/var/www/html/wp-content/themes/mytheme
- ./wordpress/wp-content/uploads:/var/www/html/wp-content/uploads
ports:
- "80:80"
depends_on:
- mysql
mysql:
image: mysql:5.7
volumes:
- mysql:/var/lib/mysql
- ./mysql-initdb.d:/docker-entrypoint-initdb.d
# Set max_allowed_packet to 256M (=32505856)
command: --max_allowed_packet=32505856
environment:
MYSQL_DATABASE: wordpress
MYSQL_ROOT_PASSWORD: ''
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
volumes:
mysql:
# Dockerfile
FROM wordpress:php7.2-apache
# 基本的には手元のwordpressを入れなおす
ADD ./wordpress /var/www/html
# 注意: .dockerignore の存在を忘れないこと。
# .dockerignore
wordpress/wp-content/uploads
wordpress/wp-content/themes/mytheme
おわりに
こんな感じで、ローカル確認が遅すぎてもはやステージングサーバーに毎回送った方が早いんじゃないかというレベルで微妙な気持ちになる開発環境が改善しました。うれしい。
僕は普段はPHPあんまり書かなくて、色々な制約から仕方なくWordPressを触ってるんですが、そういう人って結構多い気がするし、そういう人はDockerで環境をコンテナに押し込みたいと思うんですよね。
Laravelとか使ってるPHP案件でも同様に使えると思う。 特にvendor以下をイメージに入れるだけでも速度面はかなりのメリットがありそう。