😍

WordpressのDocker環境作成 (PHP8, apache, MariaDB, Xdebug)

2023/01/14に公開

目的

docker環境の生成は、過去に作った環境をコピーすれば躓くことはほぼないが、初めて作る場合は、予期しないエラーに躓き、非常に時間を食うことが多い。
よって、筆者がテンプレート化している環境のうち、今回は、wordpress環境をさくっと作るテンプレートを紹介する。

PHP8, apache, MariaDB, XdebugによるDocker環境の作成で汎用的なlampのDocker環境の作り方を記載したが、wordpressも同じ構成で簡単に構築することができる。
めちゃくちゃ使える有料級の記事なので、是非ともいいねをお願いしたい。
好評であれば、laravelやその他のフレームワークのDocker環境も随時紹介していこうと思う。

バージョン情報

  • 手元の作業PC: Apple M1 Pro
  • Docker: 20.10.21
    • イメージ: php:8.1-apache
    • イメージ: mariadb:10.3
    • イメージ: phpmyadmin:latest
    • イメージ: mailhog/mailhog:latest
  • wordpress: 6.1.1
  • PHP: 8.1
  • DB: mariadb 10.3
  • Docker-compose: 2.13.0

ゴール

http://localhost でwordpressのページが表示されること

ディレクトリ構成

プロジェクトルート
├── .vscode
│    └── launch.json (vscode エディタのデバッガー設定)
├── www
│    └── html
│         ├── index.php
│         ├── .htaccess
│         ├── license.txt
│         ├── readme.html
│         ├── wp-activate.php
│         ├── wp-admin
│         ├── wp-blog-header.php
│         ├── wp-comments-post.php
│         ├── wp-config-docker.php
│         ├── wp-config-sample.php
│         ├── wp-config.php
│         ├── wp-config.php.org
│         ├── wp-content
│         ├── wp-cron.php
│         ├── wp-includes
│         ├── wp-links-opml.php
│         ├── wp-load.php
│         ├── wp-login.php
│         ├── wp-mail.php
│         ├── wp-settings.php
│         ├── wp-signup.php
│         ├── wp-trackback.php
│         └── xmlrpc.php
├── docker-compose.yml
├── (docker-compose.tmp.yml) * 初回のみ必要
├── .env (環境変数を隠すため)
├── .gitignore (.envをgitに誤ってあげないため)
└── docker
    ├── app
    │    ├── apache2
    │    │    ├── sites-available
    │    │    │   └── 000-default.conf
    │    │    └ apache2.conf
    │    ├── php.ini
    │    └── Dockerfile
    ├── msmtp
    │    └── msmtprc (メール送信のSMTP設定用)
    └── mysql
         ├── initdb (sqlの初期化用)
         ├── storage (データのマウント用)
         ├── Dockerfile
         └── server.cnf

手順

はじめに、こちらはPHP8, apache, MariaDB, XdebugによるDocker環境の作成の続編シリーズなので、手元に同じテンプレートがある前提で記載しています。

また、手順は2パターンに分けて、それぞれ手順を記載しております。

  • パターンA: 本番やステージングなど、すでに稼働しているwordpressが存在する場合
  • パターンB: 稼働しているwordpressが存在しない場合

[パターンAの人用]

手順1. www/htmlの中に稼働しているリモートのwordpressをコピー

FTPソフトなり、rsyncなりでwordpressの一式をダウンロードして、www/htmlの中に配置してください。

手順2. wordpressのデータベースのダンプファイルを取得

データベースのクライアントツールなり、mysqlのダンプコマンドなりでダンプファイルを取得してください。

TablePlus(データベースクライアントの1つ)のキャプチャ

手順3. docker/mysql/initdbに初期化用のSQLファイルを配置

手順1で作ったダンプファイルを1_dump.sqlなどの名前でリネームし、docker/mysql/initdbディレクトリに配置する (1_xxxx.sql の xxxxはなんでも良い)

次に、localhostで動くように、docker/mysql/initdb/2_change_domain.sqlを作成する。 (https://domain.exampleは 自分の稼働サイトのドメイン)

docker/mysql/initdb/2_change_domain.sql
UPDATE wp_options SET option_value=REPLACE(option_value,"https://domain.example","http://localhost");
UPDATE wp_posts SET post_content=REPLACE(post_content,"https://domain.example","http://localhost");
UPDATE wp_posts SET guid=REPLACE(guid,"https://domain.example","http://localhost");
UPDATE wp_postmeta SET meta_value=REPLACE(meta_value,"https://domain.example","http://localhost");

手順4. docker-compose.ymlの環境変数を稼働しているwordpressと同じものにする

MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD, MYSQL_ROOT_PASSWORD, PMA_USER, PMA_PASSWORDが該当します。

(gitなどで外部公開する際は、.envで環境変数の値を隠してください)

手順5. dockerビルド、起動

docker-compose build
docker-compose up -d

DBの初期化にはそこそこ時間かかります、docker-compose logs -f mysql で、進行状況を確認しながら待ちましょう。
http://localhost でアクセスできれば終わりです。
慣れてしまえば楽ちんです。

[パターンBの人用]

手順1. .envを作成

.env (環境変数で中身を隠したいものを記述)
# -------------------------------------------
# mysqlコンテナの設定
# -------------------------------------------
MYSQL_HOST=mysql
MYSQL_ROOT_PASSWORD=test_root_pass
MYSQL_DATABASE=test_db_name
MYSQL_USER=test_user
MYSQL_PASSWORD=test_pass

# -------------------------------------------
# wordpress認証用ユニークキーとソルト
# -------------------------------------------
AUTH_KEY=
SECURE_AUTH_KEY=
LOGGED_IN_KEY=
NONCE_KEY=
AUTH_SALT=
SECURE_AUTH_SALT=
LOGGED_IN_SALT=
NONCE_SALT=

.gitignoreも作りましょう

.gitignore (gitにあげないファイル記述)
.DS_Store
.env

docker-compose.ymlも.envの変数で置き換えちゃってください

docker-compose.yml
version: "3"
services:
  app:
    build:
      context: "docker/app/"
    ports:
      - 80:80
    working_dir: /var/www
    volumes:
      - "./www/:/var/www"
      - "./docker/app/apache2/apache2.conf:/etc/apache2/apache2.conf"
      - "./docker/app/apache2/sites-available/000-default.conf:/etc/apache2/sites-available/000-default.conf"
      - "./docker/msmtp/msmtprc:/etc/msmtprc"
    depends_on:
      - mysql
      - mailhog
    env_file: 
      - .env
  mysql:
    build:
      context: "docker/mysql/"
    command: --default-authentication-plugin=mysql_native_password
    environment:
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_HOST=${MYSQL_HOST}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - TZ=Asia/Tokyo
    volumes:
      - "./docker/mysql/storage/:/var/lib/mysql"
      - "./docker/mysql/initdb/:/docker-entrypoint-initdb.d"
    ports:
      - "3306:3306"
  phpmyadmin:
    image: phpmyadmin:latest
    ports:
      - 8080:80
    environment:
      - PMA_HOST=${MYSQL_HOST}
      - PMA_USER=${MYSQL_USER}
      - PMA_PASSWORD=${MYSQL_PASSWORD}
    depends_on:
      - mysql
  mailhog:
    image: mailhog/mailhog:latest
    ports:
      - "8025:8025"
      - "1025:1025"

手順2. docker-compose.tmp.ymlを作成

docker-compose.tmp.yml
version: "3"
services:
  app:
    depends_on:
      - mysql
    image: wordpress:latest
    ports:
      - "80:80"
    working_dir: /var/www/html
    volumes:
      - "./www/html:/var/www/html"
    restart: always
    environment:
      WORDPRESS_DB_HOST: ${MYSQL_HOST}:3306
      WORDPRESS_DB_USER: ${MYSQL_USER}
      WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD}
  mysql:
    build:
      context: "docker/mysql/"
    command: --default-authentication-plugin=mysql_native_password
    environment:
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_HOST=${MYSQL_HOST}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - TZ=Asia/Tokyo
    volumes:
      - "./docker/mysql/storage/:/var/lib/mysql"
      - "./docker/mysql/initdb/:/docker-entrypoint-initdb.d"
    ports:
      - "3306:3306"

手順3. Dockerをビルド、起動

docker-compose -f docker-compose.tmp.yml build
docker-compose -f docker-compose.tmp.yml up -d

手順4. wordpressの初期インストールを行う

http://localhost にアクセスし、画面案内に従って、インストールを行う。
ここでは、ファイルが欲しいのではなく、wordpressの初期DBを自動構築することが目的です。


また、wp-config.phpがhtmlディレクトリにできるので、

.envのAUTH_KEY,SECURE_AUTH_KEY,LOGGED_IN_KEY,NONCE_KEY,AUTH_SALT,SECURE_AUTH_SALT,LOGGED_IN_SALT,NONCE_SALTにコピペしてください。

.env
# -------------------------------------------
# mysqlコンテナの設定
# -------------------------------------------
MYSQL_HOST=mysql
MYSQL_ROOT_PASSWORD=test_root_pass
MYSQL_DATABASE=test_db_name
MYSQL_USER=test_user
MYSQL_PASSWORD=test_pass

# -------------------------------------------
# wordpress認証用ユニークキーとソルト
# -------------------------------------------
AUTH_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SECURE_AUTH_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
LOGGED_IN_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NONCE_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
AUTH_SALT=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SECURE_AUTH_SALT=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
LOGGED_IN_SALT=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NONCE_SALT=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

手順5. 用済みのファイルと環境を削除

手順4を終えた段階で、wordpressのデータベースが手に入ったので、この環境は一旦用済みです。
以下コマンドで、不要なものを削除しましょう

docker-compose -f docker-compose.tmp.yml down
rm -rf www/html/*
rm -rf docker-compose.tmp.yml

手順6. 最新のwordpressをダウンロード

wordpress公式ページ から、最新のwordpressをダウンロードしましょう。
ダウンロードしたものを、www/htmlに配置してください。

手順7. wp-config.phpを上書き

www/html/wp-config.php
<?php
/**
 * The base configuration for WordPress
 *
 * The wp-config.php creation script uses this file during the installation.
 * You don't have to use the web site, you can copy this file to "wp-config.php"
 * and fill in the values.
 *
 * This file contains the following configurations:
 *
 * * Database settings
 * * Secret keys
 * * Database table prefix
 * * ABSPATH
 *
 * @link https://wordpress.org/support/article/editing-wp-config-php/
 *
 * @package WordPress
 */

// ** Database settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', getenv('MYSQL_DATABASE') );

/** Database username */
define( 'DB_USER', getenv('MYSQL_USER') );

/** Database password */
define( 'DB_PASSWORD', getenv('MYSQL_PASSWORD') );

/** Database hostname */
define( 'DB_HOST', getenv('MYSQL_HOST') );

/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8' );

/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );

/**#@+
 * Authentication unique keys and salts.
 *
 * Change these to different unique phrases! You can generate these using
 * the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}.
 *
 * You can change these at any point in time to invalidate all existing cookies.
 * This will force all users to have to log in again.
 *
 * @since 2.6.0
 */
define( 'AUTH_KEY',         getenv('AUTH_KEY') );
define( 'SECURE_AUTH_KEY',  getenv('SECURE_AUTH_KEY') );
define( 'LOGGED_IN_KEY',    getenv('LOGGED_IN_KEY') );
define( 'NONCE_KEY',        getenv('NONCE_KEY') );
define( 'AUTH_SALT',        getenv('AUTH_SALT') );
define( 'SECURE_AUTH_SALT', getenv('SECURE_AUTH_SALT') );
define( 'LOGGED_IN_SALT',   getenv('LOGGED_IN_SALT') );
define( 'NONCE_SALT',       getenv('NONCE_SALT') );

/**#@-*/

/**
 * WordPress database table prefix.
 *
 * You can have multiple installations in one database if you give each
 * a unique prefix. Only numbers, letters, and underscores please!
 */
$table_prefix = 'wp_';

/**
 * For developers: WordPress debugging mode.
 *
 * Change this to true to enable the display of notices during development.
 * It is strongly recommended that plugin and theme developers use WP_DEBUG
 * in their development environments.
 *
 * For information on other constants that can be used for debugging,
 * visit the documentation.
 *
 * @link https://wordpress.org/support/article/debugging-in-wordpress/
 */
define( 'WP_DEBUG', false );

/* Add any custom values between this line and the "stop editing" line. */



/* That's all, stop editing! Happy publishing. */

/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
	define( 'ABSPATH', __DIR__ . '/' );
}

/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';

手順8. Dockerをビルド、起動

docker-compose build
docker-compose up -d

localhostにアクセスして、画面案内に従ってアップグレードしましょう

アップグレード完了したら終わりです。

確認

  • WEBページ確認

  • メール確認

$ docker-compose exec app bash

root@f761b2f53458:/var/www# php -r "mail('test@example.com', 'テストタイトル', 'テスト本文', 'From: from@example.com');";

  • デバッガー確認
    www/html/wp-includes/version.phpなり、wp-config.phpにブレークポイントを仕込んで試す。

最後に

wordpressの環境は、初期化SQLとhtmlディレクトリの中身を置換すれば、他の案件でも使い回すことができるので、非常に便利です。
自分の手元にテンプレートを一個持っておくと、この上なく便利なので、ぜひ作ってみてください。
なお、ガチの運用で使っているMySQLの認証情報などは一般公開しているリポジトリに絶対にあげないでください。(テスト用ならOK)
絶対にプライベートリポジトリにしましょう。
その上で環境変数で置き換えておくと、なお良いです。

余談ですが、記事の中で出てきたドメインに関わる影響箇所を書き換えるSQLは、wordpress案件で異なるドメイン環境を作ったり、ローカル環境作成などで、たびたび使用する重要クエリなので、永久保存版です。

UPDATE wp_options SET option_value=REPLACE(option_value,"https://domain.example","http://localhost");
UPDATE wp_posts SET post_content=REPLACE(post_content,"https://domain.example","http://localhost");
UPDATE wp_posts SET guid=REPLACE(guid,"https://domain.example","http://localhost");
UPDATE wp_postmeta SET meta_value=REPLACE(meta_value,"https://domain.example","http://localhost");

Discussion