Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連以外

lvh.me ドメインを使って、サブドメイン形式の WordPress マルチサイトの Docker 開発環境構築をしよう

と言う話が世の中に出回ってない気がするので俺が書いておくか、ってだけの記事です。単に採用例が少ない可能性もありますが、実体験としてたまに案件として遭遇する以上、知ってて損はないでしょう。

懲りずに初歩的な使い方しかしない Docker の記事出します。ebi です。よろしくお願いします。

サブドメイン形式の WordPress マルチサイトとは?

みんな大好き WordPress ですが、マルチサイト機能もサポートしています。

マルチサイトを作成するにあたって、サブディレクトリ形式(例: http://example.com/main と http://example.com/sub )で作るかサブドメイン形式(例: http://www.example.com と http://sub.example.com )で作るかを選べます

サブドメイン形式の WordPress の開発環境構築で困ること

サブドメイン形式の WordPress マルチサイトの場合は見ての通り、URL にサブドメイン付きが前提となるため、hosts ファイルを触らずとも使用できる localhost とポート番号の割り振りでは環境構築ができません。
そこで、サブドメインも自由に使えるループバックドメインとして提供されている lvh.me ドメインを利用することで、エンジニアなら誰でも面倒な設定なしにすぐ使える Docker 開発環境を用意できるのです

地道に開発環境構築をする際の話については、入社して間もない時代に取り組んだので以前 Techracho 記事にしています。
Docker 環境が上手くハマる場合、本当に何も分からなくてもすぐに開発環境を用意できる便利さがありますが、自ら Apache や MySQL の設定を行うことで、Apache による Web サーバ側の設定やリクエスト処理、Web サーバへのアクセスに関わる流れを理解しておくこともエンジニアとして非常に大事だとは思います。

lvh.me ドメインとは

localhost のように、127.0.0.1 のローカルループバックドメインとして使えるドメインです。今回利用しようとする WordPress に限らず、色んなケースで利用されます。

ただ、その存在自体は知られているものの、誰がいつから始めているのかとかの実態を取り上げている人があまり発見できず、詳細がいまいち分からなかった……。

調べて見ると、Levi Cook と言う方が、lvh.me のオーナーですと語っている GitHub Gist がありました。書かれたのはなんと10年前。少なくともこれより前からあるのでしょうか? 🤔
より詳しい出自を知っている方がいたら教えてください……。

ともあれ、大事なのは example.com や localhost のような RFC で定められた予約済みドメインではない。と言うことです。
いつ使えなくなってもおかしくないものではあるため、本記事に記載される lvh.me ドメインの利用にあたっても自己責任でお願い致します。

マルチサイトのメリット・デメリット

ついでなので、マルチサイトに関しての、簡単なメリット・デメリットを述べておくと……

  • ユーザ管理が一括化されるため、複数サイトの管理者ユーザ発行をまとめて行え、ログイン情報も共有されるため、同時に複数サイトの編集、作業を行う際にログインを要求される回数は一度で済む
  • マルチサイト間で投稿情報の取得、利用などをしたい場合、一時的なサイト切り替えのために用意されたメソッドがあるため、通常のサイト改修と近いノリで改修できる。
  • WordPress 本体、プラグインのバージョン管理が一括化されるため、WordPress 本体の更新やプラグイン更新をまとめて行える
  • 一方で、WordPress 本体の更新やプラグインの更新は、PHP のバージョンなどの兼ね合いで、思わぬエラーを生み出す恐れがあるが、複数サイト全体となると一度に確認するのは大変なため、不具合が放置されるリスクなどが大きくなる
  • 似たような話で、更新が遅い一部のプラグインのために、WordPress のバージョンをなかなか上げることができない、となると全てのサイトに影響が出てしまう
  • また、そもそもマルチサイトに対応していないプラグインなどがあって使いたい機能が使えない場合が出てくる
  • サイト素材は共通となるため、WordPress サイト以外にも静的ページなどを共存させたい場合、何もしないと全てのドメインで利用できる状態になってしまう。
    例 : メインサイト向けに何かの特設 LP を WordPress とは別に作って http://www.example.com/special_lp/ を公開したが、実は http://sub.example.com/special_lp/ でも表示できてしまう

前半のメリットが強く生きる要求、運用体制が取られるのであれば有効な手段となることもあるでしょう。
ただ、そうでなければ、シンプルな WordPress サイトから逸脱した構成になって、思いもせぬ対応が増えていくだけであるため、無暗にマルチサイト化するものではない。と言ったところが個人的な意見です。

実際に Docker 開発環境でサブドメイン形式の WordPress マルチサイトを作成してみる

最初の初期構築を担当することもあるでしょう。
実際に Docker 開発環境を利用しつつ、サブドメイン形式の WordPress マルチサイトのベースを用意してみましょう。

Dockerfile、docker-compose.yml の準備

基本的には、WordPress 公式の Docker Hub の内容に従うだけです。
volume マウントする対象をどうするかとか、Git 管理の話とか何気に話せば色々な話はあるのですが、今回の記事中では割愛します。

  • Dockerfileの例

wp-cli を入れておくと何かと便利なので、その差分だけ追加しておきます。問合せフォーム等を備えるサイトの場合は、その準備なども追加しましょう。

FROM wordpress:5.4-php7.2-apache

# install wp-cli
RUN set -ex; \
  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
  • docker-compose.ymlの例
version: '3.1'

services:

  wordpress:
    build: .
    ports:
      - 80:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: username
      WORDPRESS_DB_PASSWORD: password
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./web_root/wp-content/plugins:/var/www/html/wp-content/plugins
      - ./web_root/wp-content/themes:/var/www/html/wp-content/themes

  db:
    image: mysql:5.7
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: username
      MYSQL_PASSWORD: password
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - db:/var/lib/mysql

volumes:
  wordpress:
  db:

サブドメイン形式のマルチサイトを初期構築する

まずは docker-compose up -d --build して Docker を起動します。
続いて、docker-compose exec wordpress bash で wordpress コンテナに接続してみます。
wp-cli が使えることを確認します。

root@1e85cf7b8b70:/var/www/html# wp --info
OS:     Linux 4.4.0-177-generic #207-Ubuntu SMP Mon Mar 16 01:16:10 UTC 2020 x86_64
Shell:
PHP binary:     /usr/local/bin/php
PHP version:    7.2.29
php.ini used:
WP-CLI root dir:        phar://wp-cli.phar/vendor/wp-cli/wp-cli
WP-CLI vendor dir:      phar://wp-cli.phar/vendor
WP_CLI phar path:       /var/www/html
WP-CLI packages dir:
WP-CLI global config:
WP-CLI project config
WP-CLI version: 2.4.0

wp-cli を利用して初期構築をします。マルチサイトを初期構築する場合は wp core multisite-install を使用します。
これで、まず http://www.lvh.me/ でアクセスできる最初のサイトが作成されます。初期構築の一環で空だったデータベース上に WordPress に必須のテーブルが準備されます。

root@a836df21415b:/var/www/html# wp core multisite-install --url=www.lvh.me --subdomains --title='Techracho Subdomain Multisite' --admin_user=admin --admin_email=admin@example.com --allow-root
sh: 1: -t: not found
Admin password: 6@LmVymg5KNB7XdgVU
Created single site database tables.
Set up multisite database tables.
Added multisite constants to 'wp-config.php'.
Success: Network installed. Don't forget to set up rewrite rules (and a .htaccess file, if using Apache).

新しいサイトの追加時には wp site create です。

root@a836df21415b:/var/www/html# wp site create --slug=sub --title='Sub Site' --allow-root
Success: Site 2 created: http://sub.lvh.me/

http://sub.lvh.me/ でアクセスできる二個目のサイトもできました。

軽く動作確認してみる

http://www.lvh.me にアクセスしてみます。

http://sub.lvh.me/ にアクセスしてみます。左上のサイト名が先ほどと違います。

管理画面にアクセスしてみます。

マルチサイト向けのネットワーク管理画面も追加されています。

あとは好きに開発を進めていくだけです。

既に運用されているサブドメイン形式の WordPress マルチサイトの環境構築をする

今度は、既に運用されている WordPress サイトの開発環境構築手順を整える例を軽く紹介します。
初期構築時との違いは、既に WordPress のために必要なテーブルなどが揃ったデータベースが存在しているため、wp core multisite-install を行う必要はありません。

使用する Dockerfile や docker-compose.yml は先ほどと同じで構いません。まず docker-compose up -d --build します。
その後は、データベースのインポートやドメイン周りの調整をします、スクリプト化すると便利ですが、環境の差異で動かない時もあると思います。

今回は initial-setup.sh を準備して、docker の立ち上げ後に sh initial-setup.sh してもらう想定で準備しました。

①データベースをインポートする

データベースのエクスポートは、ここではあまり解説しません。
サイトによっては、顧客情報等が含まれる恐れもあるため、Git リポジトリの一環で管理しない方が良い場合もあると思いますので、取り扱いには十分に気を付けましょう。

MySQL イメージで構築したdb コンテナには、ちゃんと MySQL クライアントプログラムが用意されているので、db コンテナにダンプファイルをコピー後、インポートを行います。

# import database
docker cp ${DUMP_FILENAME} $(basename $(pwd))_db_1:/
docker-compose exec -T db mysql -u${MYSQL_USERNAME} -p${MYSQL_PASSWORD} ${MYSQL_DATABASE} < ${DUMP_FILENAME}

docker cp を実行する際のコンテナ名は、親ディレクトリ名_サービス名_1 になっている前提で書いているので、もしも環境によって別のコンテナ名になっている場合は調整が必要です

データベースがかなり大きいサイズのサイトの場合、MySQL server has gone away のエラーが発生して、インポートが途中で中断してしまう場合があります。
その場合は、max_allowed_packet の設定をデータベースのサイズ以上に設定しなおす必要があります。

②ドメイン名の置換を行う

本番環境のドメイン名を、開発環境用に使用する lvh.me ドメインに変更しましょう。
wp-cli のパッケージ内には、以前も紹介した Search Replace DB を応用したコマンド wp search-replace が含まれています。今回はこちらを使います。

# replace domain
docker-compose exec -T wordpress wp search-replace 'https://'${PROD_WWW_FQDN} 'http://'${LOCAL_WWW_FQDN} --allow-root --all-tables
docker-compose exec -T wordpress wp search-replace 'https://'${PROD_SUB_FQDN} 'http://'${LOCAL_SUB_FQDN} --allow-root --all-tables
docker-compose exec -T wordpress wp search-replace ${PROD_WWW_FQDN} ${LOCAL_WWW_FQDN} --allow-root --all-tables
docker-compose exec -T wordpress wp search-replace ${PROD_SUB_FQDN} ${LOCAL_SUB_FQDN} --allow-root --all-tables

一般的なサイトは、https サイトとして運用される時代だと思うので、開発環境時には http アクセスできるように、プロトコルの置換も忘れずにしておきましょう。

③wp-config.php の調整を行う

マルチサイト化を行う際には、wp-config.php への設定追記が行われています。
wp config set コマンドを利用して、マルチサイト向けの設定を自分で追記します。
本当は wp-config.php にマルチサイトに必要な設定の追記のみを行うコマンドがあると良かったのだけど見当たらず…… 🤔

# update wp-config.php for subdomain multisite
docker-compose exec -T wordpress wp config set WP_ALLOW_MULTISITE true --raw --allow-root
docker-compose exec -T wordpress wp config set MULTISITE true --raw --allow-root
docker-compose exec -T wordpress wp config set SUBDOMAIN_INSTALL true --raw --allow-root
docker-compose exec -T wordpress wp config set DOMAIN_CURRENT_SITE ${LOCAL_WWW_FQDN} --allow-root
docker-compose exec -T wordpress wp config set PATH_CURRENT_SITE / --allow-root
docker-compose exec -T wordpress wp config set SITE_ID_CURRENT_SITE 1 --raw --allow-root
docker-compose exec -T wordpress wp config set BLOG_ID_CURRENT_SITE 1 --raw --allow-root

ちなみに、wp config set コマンドを利用することで、デバッグモードの ON・OFF も、wp config set WP_DEBUG true --raw --allow-root 等の実行で行えます。


以上の流れで、基本的な開発環境構築は終わりです。
サイトの性質に応じて、必要な処理などを追加していきましょう。

今回は割愛していますが、WordPress コンテナの作成時には初期テーマが追加されてしまいます。不要な場合は、その整理なども追加してください( gitignore するだけで十分かもしれない)。


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。