はじめに
今更 WordPress かと思われますが、世の中の 35.8% の Web サイトが WordPress で作成されていると聞くと無視することはできません。例に漏れず当ブログも WordPress で構築されているのですが、開発時には Docker Compose を用いてさくっとローカル開発環境を構築しました。
さくっと?嘘です(笑)
ドッカーのドの字も知らなかった私は調子をこいて MAMP ではなく、Docker と Docker Compose を選択したのです。メチャクチャ苦労しました。と言うのも当初は Docker 公式ガイドの WordPress の docker-comppose.yml を利用していたのですが、これが使いづらく、どうしても内部の処理まで踏み込む必要があったためです。
そこで、今回は個人的にですが、ある程度開発しやすいだろう docker-compose.yml を共有したいと思います。こちらを使えば、おそらく、さくっとローカル環境を作れると思います 💦
現在、当ブログは WordPress ではなく Gatsby.js で構築されています 🙇♂️
やりたいこと
下記の観点で docker-compose.yml を作成しています。
- Nginx を Web サーバに採用
- ミドルウェア単位でコンテナ化
- Alpine ディストリビューションで軽量化を目論む
- phpMyAdmin も添えて開発し易く
Docker、Nginx、Mysql、PHP で構築しているので頭文字を取って DNMP(ディエヌエムピー) と勝手に呼んでいます 😅
Github にも置いているので参考にしてもらえればと思います。
検証環境
- macOS Catalina バージョン 10.15.3
- docker desktop community Version 2.2.0.3
docker-compose.yml in DNMP...
だらだら説明するより、 今回作成した docker-compose.yml と Nginx の default.conf を見てもらえたらと思います。
docker-compose.yml
1version: "3"
2
3services:
4 db:
5 image: mysql:5.7
6 volumes:
7 - ./mysql/db:/var/lib/mysql
8 restart: always
9 environment:
10 MYSQL_ROOT_PASSWORD: wordpress
11 MYSQL_DATABASE: wordpress
12 MYSQL_USER: wordpress
13 MYSQL_PASSWORD: wordpress
14
15 phpmyadmin:
16 image: phpmyadmin/phpmyadmin:fpm-alpine
17 volumes:
18 - shared_phpmyadmin:/var/www/html
19 - ./phpmyadmin/sessions:/sessions
20 depends_on:
21 - db
22 restart: always
23 environment:
24 PMA_HOST: db:3306
25
26 wordpress:
27 image: wordpress:php7.3-fpm-alpine
28 volumes:
29 - shared_wordpress:/var/www/html
30 - ./mytheme:/var/www/html/wp-content/themes/mytheme
31 depends_on:
32 - db
33 restart: always
34 environment:
35 WORDPRESS_DB_HOST: db:3306
36 WORDPRESS_DB_PASSWORD: wordpress
37
38 nginx:
39 image: nginx:stable-alpine
40 volumes:
41 - shared_wordpress:/var/www/html
42 - shared_phpmyadmin:/var/www/html/phpmyadmin
43 - ./mytheme:/var/www/html/wp-content/themes/mytheme
44 - ./default.conf:/etc/nginx/conf.d/default.conf
45 ports:
46 - 8000:80
47 depends_on:
48 - phpmyadmin
49 - wordpress
50 restart: always
51
52volumes:
53 shared_wordpress:
54 driver: local
55 shared_phpmyadmin:
56 driver: local
default.conf
1server {
2
3 listen 80;
4 listen [::]:80;
5 server_name localhost;
6
7 root /var/www/html;
8 index index.php index.html index.htm;
9
10 access_log /var/log/nginx/access.log;
11 error_log /var/log/nginx/error.log;
12
13 location / {
14 try_files $uri $uri/ /index.php$is_args$args;
15 }
16
17 # wordpress
18 location ~ \.php$ {
19 include fastcgi_params;
20 try_files $uri =404;
21 fastcgi_split_path_info ^(.+\.php)(/.+)$;
22 fastcgi_pass wordpress:9000;
23 fastcgi_index index.php;
24 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
25 fastcgi_param PATH_INFO $fastcgi_path_info;
26 }
27
28 # phpmyadmin
29 location ^~ /phpmyadmin {
30
31 alias /var/www/html/phpmyadmin;
32 try_files $uri $uri/ @phpmyadmin;
33
34 location ~ ^/phpmyadmin/(.+\.php)$ {
35 include fastcgi_params;
36 fastcgi_split_path_info ^\/phpmyadmin\/(.+\.php)(.*)$;
37 fastcgi_pass phpmyadmin:9000;
38 fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
39 }
40 }
41}
volumes で何をどこにマウントしたいのか?
今回結構詰まったのが docker-compose.yml におけるマウントの扱い方でした。と言うのも何をマウントしたいのかを明確に理解しないと思ったように動かなかったためです。docker-compose.yml の volumes でマウントする際に、ローカルとコンテナ間をマウントしたいのか、それともコンテナ間でマウントしたいのか、を明確に区別して理解することが結構重要だと思われます。
ローカルとコンテナの間のマウント
ローカルからコンテナへのマウントは、基本ローカルでゴリゴリと編集するソースや設定ファイル、もしくはローカルで永続化したいデータかと思います。コンテナは起動終了するとそれまで編集していたデータが消えてしまいます。そのため、自身で編集したファイルを終了する前にローカルに保存するか、もしくはコンテナからマウントするかでローカルに永続化させます。
1## ローカルの設定ファイルをコンテナのnginxにマウントする場合
2volumes:
3 - ./sample.conf:/etc/ngin/conf.d/sample.conf
4
5## mysqlのデータをローカルにマウントして永続化する場合
6volumes:
7 - ./.data/db:/var/lib/mysql
コンテナとコンテナの間のマウント
対して、コンテナ間のファイルやディレクトリを同期したい場合は、ローカルはあくまでも中継地点になるかと思います。下記はローカルを経由して WordPress コンテナ内の /wordpress
ディレクトリを nginx コンテナの公開ディレクトリにマウントする例です。
1wordpress:
2 volumes: shared_source:/var/www/html/wordpress
3
4nginx:
5 volumes: shared_source:/var/www/html
6
7volumes:
8 shared_source:
9 driver: local
コンテナ間でマウントされた場所の子ディレクトリにローカルから何かをマウントした場合、その何かはコンテナ間で共有化できない
表題が長いですが、言いたいことはそれです(汗) 結構詰まったのですが、文章で説明するとピンと来ないかもしれないので、下記の例を見てもらえればと思います。
ダメな例 ×
1wordpress:
2 volumes:
3 - shared_wordpress:/var/www/html
4 - ./mytheme:/var/www/html/wp-content/themes/mytheme
5
6 nginx:
7 volumes:
8 - shared_wordpress:/var/www/html
良い例 ◯
1wordpress:
2 volumes:
3 - shared_wordpress:/var/www/html
4 - ./mytheme:/var/www/html/wp-content/themes/mytheme
5
6 nginx:
7 volumes:
8 - shared_wordpress:/var/www/html
9 - ./mytheme:/var/www/html/wp-content/themes/mytheme
2つの例では、./mytheme
を wordpress コンテナの /var/www/html/themes/mytheme
にどちらもマウントしているのですが、ダメな例では、同ディレクトリを nginx 側にはマウントしていません。一見、ダメな例では親ディレクトリの /var/www/html
をコンテナ間でマウントしているので、自ずとその子ディレクトリの /var/www/html/themes/mytheme
も共有されると考えていたのですが、nginx コンテナ側の該当ディレクトリには何も存在しませんでした。
そのため、コンテナ間でマウントしている場所に、ローカルから何かをマウントする場合は、各コンテナの同一のディレクトリにマウントする必要があります。
おわりに
今回作成した Docker Compose を使うことで、ローカル開発環境であればコマンド1つで簡単に環境を構築することが出来るようになると思います。 インフラを何回もスクラップ&ビルドする Docker と Docker Compose を使うことで、WordPress のサーバー環境依存をある程度低減することもできます。
ですが、それでも本番でコンテナ運用するにはまだまだ課題点だらけです。 コアファイルの wp-config.php を如何にコンテナ起動時に制御するのか、wp-content のパーミッション変更をどのように自動化するのか、などなど、やることは山のようにあります、、、
長くなるので今回はここまでにして、またどこかでその話をできればと思います(汗)