WordPressの開発環境に XAMPP や Vagrant を使った来たのですが、そろそろ今どきの環境にアップデートしないと取り残されそうだったので WSL2 と Docker desktop for windows をいれ、いろいろ試してみました
Docker desktop for windows のインストールは、たくさんの紹介記事があるのでここでは紹介しませんが、Docker を使ってみた感想や作成した WordPress 開発環境用の docker-compose ファイル等の紹介をします
Docker にとまどう
Docker ってなんとなく今まで使っていた Vagrant と同じようなものと思っていましたが、まったく違っていました。
Vagrant がいわゆる仮想マシンでそのマシン内にオールインワン的に必要なサービスやアプリを全て詰め込んだものだったのですが、Dockerは、コンテナというサービスやアプリ毎の最小限の動作を行う部品を作成し、それらの部品を組み合わせることで目的の動作をおこなわせるという手法をとります
目的の動作を実現する部品(コンテナ)の組み合わせるだけです
この部品(コンテナ)を組み合わせるためのツールとして docker-compose と言うのが用意されているので、実際は Docker を単独で実行することは少なく、ほとんどの場合で docker-compose を使って実行することとなります
うーん。うまく説明できません (^_^;)
なにせまだ1か月ぐらいしか使ってませんので、わからないことだらけです。Webには情報がたくさんありますからいろいろググってみてください
とりあえず下記サイトが参考になります
今までの必要なものをLinux上に追加しながら構築していくという感覚は一旦捨てて新しいやり方に慣れる必要があります
コンテナに必要なものを追加したいのに、Docker の作法に従わないと破棄されてなんで消えちゃったの ??? とか、コンテナ毎に隔離されているので、コマンドは使えないとか、ファイルにアクセスできないとか、今までの常識が通用しないのでこの独特の環境になれるしかありません
まあ、戸惑ってばかりでもしょうがないので、WordPress 開発環境用コンポーザファイルを作成してみました
このコンポーザファイルも、悩みながら試行錯誤しつつ、数百サイトの記事を参考にしてようやく作り上げたものです。ぜひ試してみて下さい
LAMP-WPDEV/LEMP-WPDEV WordPress 開発環境
一般的な Linux-Apache-Mariadb-Php (LAMP) または Linux-Nginx-Mariadb-Php (LEMP) を PHP8.1/8.2 Fast-cgi で構成し、wp-cli を使って WordPress をインストールする開発用環境
サーバーが Apach か Nginx かで異なりますが、他はほとんど同じ構成となりますのでお好きな方をご利用ください
開発作業では WP_DEBUG は true が望ましいのですが、WordPress側の PHP8.1/8.2 対応が遅れていて Depricated のエラーが多数表示されるため wp-config.php ファイルの WP_DEBUG を false にして表示を抑制しています。必要に応じて書き換えて下さい
使用イメージ
- php8.1-fpm-alpine / php8.2-fpm-alpine 公式イメージを wordpress 用にカスタマイズ
- Apach httpd2.4-alpine または nginx 1.22.1-alpine 公式イメージ
- Database mariadb10.5 公式イメージ
https://github.com/mzazon/php-apache-mysql-containerized
ダウンロード
LAMP(Apache) PHP8.1 版
LEMP(Nginx) PHP8.2 版
ダウンロードボタンをクリックするとパスワード入力ページが表示されるので、パスワード( wpdev )を入力してダウンロードして下さい
パスワードを入力すると自動的にダウンロードが実行されます
ファイル構成
Windowsの任意のディレクトリフォルダーで lamp_wpdev-x.x.x.zip を解凍すると下記ファイル構成に展開されます
apache/ | Dockerfile | httpd イメージビルドファイル |
my.apache.conf | ロードモジュールと php-fpm の Virtual Host 構成定義ファイル | |
my.ssl.conf | https 通信用の構成定義ファイル | |
server.crt | ※mkcert を使って自己証明書を作成して上書きコピーして置き換えてください | |
server.key | ※mkcert を使って自己証明書を作成して上書きコピーして置き換えてください | |
php/ | Dockerfile | php-fpm イメージビルドファイル |
php.ini | php 定義ファイル(xdebug 定義含む) | |
php.ini.development | php 定義ファイルサンプル | |
php.ini.production | php 定義ファイルサンプル | |
public_html/ | dbtest.php | データベース動作確認用 |
phpinfo.php | php-fpm 動作確認用 | |
.htaccess.dev | .htaccess のテンプレートファイル | |
wp-install.sh | wp-cli を使った WordPress インストール用のシェルファイル | |
.env | 構築する Apache/Nginx, PHP, DB のバージョン等を設定します | |
docker-compose.yml | lamp_wpdev コンポーズファイル本体 | |
readme.txt | lamp_wpdev/lemp_wpdev コンポーズファイルの説明書 |
LEMP版では、apache の代わりに nginx となり、nginx フォルダは下記ファイル構成となります
nginx/ | Dockerfile | nginx イメージビルドファイル |
default.conf | Nginx 構成定義ファイル | |
server.crt | ※mkcert を使って自己証明書を作成して上書きコピーして置き換えてください | |
server.key | ※mkcert を使って自己証明書を作成して上書きコピーして置き換えてください |
WSL2 の Linux(ubuntu等)からの実行について
Windowsのフォルダーから実行して Docker クライアントとファイル共有するのが簡単で扱いやすいのですが、デメリットとして、Windows と Linux の異なるファイルシステム間でのファイル共有はファイルアクセスが遅くなるという影響があります。また、node を使用した npm の JavaScript 開発においてはファイルの変更を検出できずに Live reload 等が使えないということもあります。
これらのデメリットが気になるようでしたらひと手間かかりますが、ターミナルを使い WSL2 上の Ubuntu 等にログインして、 home ディレクトリのログインユーザー下に workspace 等の作業ディレクトリを作ってファイルを展開、そこから Docker で docker-compose.yml を実行することをおすすめします。
ターミナルでLinux(Ubuntu等)へのログイン後は、作業用ディレクトリへ移り、そこから code .
と入力するだけでVSCodeが起動出来るので、以降の作業は Windows 上での操作と同じ感覚で行えると思います
このように VSCode では、簡単に WSL Linux 上で実行出来るようになっているのですが、Windowsで使っているエディタや NetBeans 等では WSL 上のファイル操作に対応していないことが多いです。このような場合にはネットワークドライブを割り当てることで対応します(wsl$Ubuntu-20.04 をドライブ名 Z: 等に割当てドライブ名を使用してアクセスすることが可能-但し、一部のファイル(SQLiteのDB等)はネットワークドライブでアクセスが制限されることもあるようです)
.env ファイル
APACHE_VERSION=2.4 PROJECT_TZ=Asia/Tokyo #docker default network bridge #このIPをコンテナ内 /etc/hosts に 172.17.0.1 localhost として追加することで WordPress サイトヘルスチェックの ecurl エラーが解消できる #注:独自ネットワークを定義するとデフォルトの 172.17.0.1 でなくコンテナ内で動的に生成されるIPとなってしまうのでデフォルトを使うこと DOCKER_HOST_IP=172.17.0.1 OWNER_USER=lamp OWNER_UID=1000 OWNER_GID=1000 PHP_VERSION=8.1 PHP_INI_DIR=/usr/local/etc/php
NODE_VERSION=18.12.1
NODE_ENV=development # DB_TYPE=mysql # DB_VERSION=5.7 DB_TYPE=mariadb DB_VERSION=10.5 DB_ROOT_PASSWORD=admin DB_NAME=dbtest DB_USERNAME=root DB_PASSWORD=admin DOCUMENT_ROOT=./public_html
LEMP版では、nginx の設定等一部異なります。詳細は LEMP版の .env ファイルを参照してください
docker-compose.yml ファイル
version: "3.8" services: php: build: context: './php/' args: PHP_VERSION: ${PHP_VERSION} user: ${OWNER_USER} uid: ${OWNER_UID} gid: ${OWNER_GID} extra_hosts: - localhost:${DOCKER_HOST_IP} volumes: - ${DOCUMENT_ROOT}/:/var/www/html/ - ./php/php.ini:${PHP_INI_DIR}/php.ini container_name: php db: image: ${DB_TYPE}:${DB_VERSION} command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci restart: always ports: - "3306:3306" volumes: - db_data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD}" MYSQL_DATABASE: "${DB_NAME}" MYSQL_USER: "${DB_USERNAME}" MYSQL_PASSWORD: "${DB_PASSWORD}" TZ: "${PROJECT_TZ}" container_name: db apache: build: context: './apache/' args: APACHE_VERSION: ${APACHE_VERSION} depends_on: - php - db ports: - "80:80" - "443:443" volumes: - ${DOCUMENT_ROOT}/:/var/www/html/ container_name: apache mailhog: image: mailhog/mailhog ports: - 8025:8025 - 1025:1025 container_name: mailhog volumes: db_data:
LEMP版では、nginx の設定等一部異なります。詳細は LEMP版の docker-compose.yaml ファイルを参照してください
Apache – Dockerfile ファイル
ARG APACHE_VERSION="" FROM httpd:${APACHE_VERSION:+${APACHE_VERSION}-}alpine #self-signed SSL certificates for localhost COPY server.crt /usr/local/apache2/conf/server.crt COPY server.key /usr/local/apache2/conf/server.key # Copy apache vhost file to proxy php requests to php-fpm container COPY my.apache.conf /usr/local/apache2/conf/my.apache.conf COPY my.ssl.conf /usr/local/apache2/conf/my.ssl.conf RUN echo "Include /usr/local/apache2/conf/my.apache.conf" >> /usr/local/apache2/conf/httpd.conf && echo "Include /usr/local/apache2/conf/my.ssl.conf" >> /usr/local/apache2/conf/extra/httpd-ssl.conf
Nginx – Dockerfile ファイル
ARG NGINX_VERSION="" FROM nginx:${NGINX_VERSION:+${NGINX_VERSION}-}alpine #self-signed SSL certificates for localhost COPY server.crt /etc/nginx/conf.d/server.crt COPY server.key /etc/nginx/conf.d/server.key # nginx config file, Nginx 設定ファイルをコンテナにコピー COPY default.conf /etc/nginx/conf.d/default.conf
php – Dockerfile ファイル
ARG PHP_VERSION="" ARG NODE_VERSION="" FROM node:${NODE_VERSION:+${NODE_VERSION}-}alpine as node FROM php:${PHP_VERSION:+${PHP_VERSION}-}fpm-alpine # Arguments defined in docker-compose.yml ARG user ARG uid ARG gid ENV TZ=${PROJECT_TZ} COPY ./php.ini ${PHP_INI_DIR}/php.ini RUN apk update; apk upgrade; apk add --no-cache linux-headers autoconf automake libtool build-base libc6-compat nasm sudo bash openssh git wget sed mysql-client findutils #ext lib RUN apk add --no-cache icu-dev curl-dev libffi-dev freetype-dev libzip-dev libjpeg-turbo-dev libpng-dev libwebp-dev libavif-dev imagemagick imagemagick-dev fftw-dev vips-tools vips-dev #ext config RUN docker-php-ext-configure zip --with-zip RUN docker-php-ext-configure intl RUN docker-php-ext-configure ffi --with-ffi RUN docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp --with-avif #ext install RUN docker-php-ext-install zip intl ffi opcache shmop sockets bcmath gd exif pdo_mysql mysqli #imagick RUN pecl install -o -f imagick && docker-php-ext-enable imagick #vips https://github.com/libvips/php-vips-ext RUN pecl install vips && docker-php-ext-enable vips #APCu RUN pecl install apcu && docker-php-ext-enable apcu #Xdebug3 RUN pecl install xdebug && docker-php-ext-enable xdebug #MailHog / mhsendmail RUN curl -sSLO https://github.com/mailhog/mhsendmail/releases/download/v0.2.0/mhsendmail_linux_amd64 && chmod +x mhsendmail_linux_amd64 && mv mhsendmail_linux_amd64 /usr/local/bin/mhsendmail #composer COPY --from=composer /usr/bin/composer /usr/bin/composer #wp-cli RUN curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && chmod +x wp-cli.phar && mv wp-cli.phar /usr/local/bin/wp # node, npm, npx for JS dev COPY --from=node /usr/local/bin/node /usr/local/bin/ COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/ RUN ln -s /usr/local/bin/node /usr/local/bin/nodejs && ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx # Create system user to run Composer Commands RUN addgroup -g $gid -S $user && adduser -u $uid -G $user -h /home/$user -D $user && echo "$user ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/$user && chmod 0440 /etc/sudoers.d/$user && adduser $user www-data RUN mkdir -p /home/$user/.composer && chown -R $user:$user /home/$user # root password: docker set RUN echo "root:docker" | chpasswd USER $user #bash prompt set ENV PS1="[u@w]$"
使用可能な画像ライブラリとして、GD / ImageMagic / Vips をインストールしているのでコンテナイメージ少し大きくなっています。不要な画像ライブラリや Webp, avif 等をコメントアウトすることでイメージを小さく出来ます
ファイルの永続化について
Windows/WSL(Linux) 側とdocker コンテナ内との共有
- docker-compose.yml ファイルのあるフォルダ下の public_html フォルダーを docker 内の /var/www/html
- php/php.ini ファイルと docker 内の /usr/local/etc/php/php.ini
Docker内での永続化
- データベース /var/lib/mysql をdocker 内で db_data 名で永続化
ネットワーク定義について
extra_hosts を使用してコンテナ内 /etc/hosts に 172.17.0.1 localhost を追加します
これをしておかないと WordPress のサイトヘルスチェックで ecurl エラーが発生します
独自ネットワークを定義するとIPアドレスがデフォルトの 172.17.0.1 でなくコンテナ内で動的に生成されるIPとなるので、ネットワークは定義せずにデフォルト(未定義)としてください
サイトヘルスチェック curl エラー対策について
以前は上記のように docker-compose で extra_host を設定すれば WordPress のサイトヘルスチェックで ecurl エラーが発生しなかったのですがいつの間にか私の環境で ecurl エラーになるようになってしまいました。そこで extra_hosts を指定しなくても済むように Docker コンテナ内から localhost に対するリクエストを host.docker.internal に置き換えるだけのプラグインを作成しました。ecurl エラーとなる場合は下記プラグインを試してみて下さい
※ Windows WSL2 環境での wp-env でも使えます 😊
使い方
準備
SSL(https) でアクセスするには、Windows 側に mkcert をインストールして自己署名証明書を作成する必要があります
https://github.com/FiloSottile/mkcert
mkcert をインストールしたらwindows側に mkcert による証明書をインストールします
mkcert -install
下記のようなダイアログが表示されるので確認してインストールしてください
次にサーバー側に設定する自己証明書を作成します
mkcert localhost 127.0.0.1 ::1
作成された localhost+2-key.pem, localhost+2.pem を apache フォルダー内 server.key, server.crt へ上書きコピーしてから docker-compose を実行してください
実行
Docker desktop for windows が実行されている状態で powershell から docker-compose up を実行
VSCode に Docker 拡張機能を入れていればファイルを選択して右クリックからメニューで GUI 操作で出来るので、キーボード入力がほとんどいらなくなります。 おすすめです (^^)
Docker(クジラ)アイコンをクリックすると詳細な情報の確認や各種操作がGUIで出来ます
初回は php と追加モジュールのコンパイルが行われるので時間がかかります
docker-compose が起動したら、下記URLにアクセスして動作確認します
http://localhost/phpinfo.php
http://localhost/dbtest.php
自己署名証明書を設定していれば、https://localhost/phpinfo.php としてもアクセスできます。ただし、Chrome では保護された通信となりますが、firefox ではブラウザ上で保護されていない通信と表示されます
php とデータベースが正常に動作していることを確認したら、wordpress のインストールを行います
WordPress インストール
WordPress は wp-install.sh シェルスクリプトを実行すると自動的にドキュメントルート下の wordpress フォルダーへインストールされます
インストール条件を変えたい場合は、必要に応じて wp-install.sh 内のパラメータを変更してください
インストール先フォルダー名を変更する場合は、LAMP版なら .htaccess.dev を LEMP版なら nginx の default.conf 内の該当箇所もあわせて変更してください
wp-install.sh ファイル
#!/bin/bash set -eu if [[ -f /var/www/html/wordpress/index.php ]]; then echo "Wordpress is already installed..." 2>&1 else #==================================================== declare DB_USERNAME=root declare DB_PASSWORD=admin declare DB_HOST=db declare OWNER_USER=lamp declare WP_VERSION=latest declare WP_DB_NAME=wordpress declare WP_INSTALLDIR=/var/www/html/wordpress declare WP_ROOT_URL=http://localhost/wordpress # declare WP_ROOT_URL=https://localhost/wordpress declare WP_SITE_TITLE=DockerTestSite declare WP_ADMIN_LOGIN=admin declare WP_ADMIN_PASSWORD=admin declare WP_ADMIN_EMAIL=example@example.com #==================================================== if [[ ! -d /var/www/html/wordpress ]]; then mkdir /var/www/html/wordpress fi if [[ ! -f /var/www/html/wordpress.htaccess ]]; then cp .htaccess.dev /var/www/html/wordpress/.htaccess chown ${OWNER_USER}:${OWNER_USER} /var/www/html/wordpress/.htaccess fi echo "Download wordpress..." 2>&1 wp core download --path=${WP_INSTALLDIR} --version=${WP_VERSION} --locale=ja echo "wp config define create" cd ${WP_INSTALLDIR} # find ${WP_INSTALLDIR}/wp-content -type d -exec chmod 775 {} ; # find ${WP_INSTALLDIR} -type f -exec chmod 664 {} ; wp core config --dbname=${WP_DB_NAME} --dbuser=${DB_USERNAME} --dbpass=${DB_PASSWORD} --dbhost=${DB_HOST} --dbcharset=utf8mb4 --dbprefix=wp_ --extra-php <<PHP
define( 'WP_DEBUG', false );
define( 'SCRIPT_DEBUG', false);
define( 'WP_DEBUG_LOG', false ); PHP echo "Installing wordpress..." # wp db drop --yes wp db create wp core install --url=${WP_ROOT_URL} --title=${WP_SITE_TITLE} --admin_user=${WP_ADMIN_LOGIN} --admin_password=${WP_ADMIN_PASSWORD} --admin_email=${WP_ADMIN_EMAIL} echo "Rewriting permalink_structure" wp option update permalink_structure "/%post_id%/%postname%/" echo "Time zone setting" wp option update timezone_string 'Asia/Tokyo' wp option update date_format 'Y-m-d' wp option update time_format 'H:i' echo "plugin install..." wp plugin install wp-multibyte-patch --activate wp plugin install query-monitor --activate wp plugin install wp-crontrol wp plugin install cb-change-mail-sender wp plugin install wordpress-beta-tester # wp plugin install theme-check wp plugin install yasakani-cache wp plugin install plugin-load-filter # wp plugin install loco-translate # wp plugin install contact-form-7 # wp plugin install classic-widgets echo "theme install..." wp theme install twentytwentyone # wp theme install hello-elementor echo "theme_unit_test install..." wp plugin install wordpress-importer --activate wget https://raw.githubusercontent.com/WPTRT/theme-unit-test/master/themeunittestdata.wordpress.xml wp import themeunittestdata.wordpress.xml --authors=create # wget https://raw.githubusercontent.com/jawordpressorg/theme-test-data-ja/master/wordpress-theme-test-data-ja.xml # wp import wordpress-theme-test-data-ja.xml --authors=create fi exit 0
wp cli に関しては、下記記事が参考になります
インストール
- wp-install.sh のパラメータを必要に応じて修正
- lamp_wpdev-php/lemp_wpdev-php コンテナへ Attach Shell してターミナル操作
- ターミナルから bash wp-install.sh 実行
- 設定内容に従って自動的に wp-cli によりインストールされます
lamp_wpdev-php/lemp_wpdev-php コンテナへ Attach Shell すると wp コマンドだけでなく、Node の npm, npx も使用できるようになっています
VSCode で Attach Shell するとそのコンテナに内の操作することができます
Docker は、仮想マシンと違いログインの代わりに、コンテナに Attach Shell することでターミナルから操作できるようになります
VSCode のターミナルが表示されるので bash wp-install.sh を実行します
public_html の下に wordpress ディレクトリが作られてインストールされます
動作確認
https://localhost/wordpress へアクセスすれば表示されるはずです
https://localhost/wordpress/wp-login.php で管理画面へログインできます
WordPress 管理者ユーザー
ユーザー : admin
パスワード: admin
次回以降は、既にインストールされている wordpress へアクセスすればOKです
メール送信テストについて
ローカルでメールテストを行える MailHog (https://github.com/mailhog/MailHog) を利用できます
WordPressのメール送信 wp_mail 関数は、localhost サイト名では送信しない仕様(ドメイン名にピリオド以下の設定が不可欠)となっていますので WordPress plugin の CB Change Mail Sender を有効化してメール送信者情報を設定する必要があります
CB Change Mail Sender の送信者情報
CB Mail Sender Name : wpdev
CB Mail Sender Email: wpdev@localhost.dev
WordPress から送信されるメールを http://localhost:8025 へアクセスするとメール内容を確認できます
Xdebug について
デバッグは、VSCode でもできるみたいですが、ここは、私の使い慣れている NetBeans を使いたいので、php.ini には、NetBeans IDE 用の xdebug3 の設定をしてあります
[XDebug] ;xdebug2 settings ;xdebug.remote_enable=1 ;xdebug.remote_connect_back=0 ;xdebug.remote_host=localhost ;xdebug.remote_host=host.docker.internal ;xdebug.remote_port=9003 ;xdebug.idekey="netbeans-xdebug" ;xdebug.remote_handler=dbgp ;xdebug3 settings xdebug.mode=debug ;xdebug.start_with_request=yes xdebug.start_with_request=trigger xdebug.discover_client_host=0 ;xdebug.client_host=localhost xdebug.client_host=host.docker.internal ;xdebug.log=/tmp/xdebug.log xdebug.client_port=9003 xdebug.idekey="netbeans-xdebug"
ポイントは、host.docker.internal を指定するところです
NetBeans 側の設定
ポート番号とidkey を合わせておきます
lamp_wpdev ディレクトリの public_html 下の wordpress をプロジェクトとして登録します
XAMPPだったらここまででよかったのですが、Docker desktop for windows の場合はもう一つマッピングの設定が必要となります
WSLのLinux(Ubuntu等)上にDockerコンテナと共有するwordpressフォルダを作成していて WindowsのNetBeans からその共有フォルダにアクセスするには、ネットワークドライブを割り当てておく必要があります
プロジェクトのプロパティから Run Configuration を指定して、Advanced ボタンをクリックします
表示された画面で、Docker 内の wordpress パスと Windows 内の wordpress パスを指定します
以上で、デバッグできるようになるのでブレークポイントを設定して確認してみて下さい
データベースへのアクセスについて
データベースの操作は、HeidiSQL について紹介します
難しい設定などはなく XAMPP 環境と同様な感じの設定であっさり接続できました
セッションマネージャーで接続ホスト名(localhost)とユーザーを登録します
データベース管理者ユーザー
ユーザー : root
パスワード: admin
開くをクリックするとこんな感じの表示となるので、後は自由にデータベースを操作することができます
以上
docker-compose.yml や Dockerfile を作成して環境を構築するのはけっこう大変ですが、作成されたものを使うだけならとっても簡単と言うことがわかりました
簡単なので(ほとんどの人は使うだけ)、Docker が人気になるのがわかったような気がします
よかったら lamp_wpdev / lemp_wpdev で遊んでみてください (^^)