Docker Composeを使ってWordPressが動作するローカル環境を作る

Docker Composeを使えばローカルにWordPressが動作する環境を手軽に作れます。テーマやプラグイン開発、WordPressの勉強にもってこいです。

はじめに

Dockerを使えばサーバーで動作するようなアプリをローカル環境で簡単に使うことができます。Dockerについてと基本的な使い方はこちらを参照してください。

ここではDocker Composeという機能を使ってより効率よく、WordPressが動作する環境をMacやWindowsに作成します。

Docker Composeについて

Docker Composeは複数のコンテナを起動するツールです。WordPressを動作させるためにはWebサーバー、PHP、データベースが必要ですが、それら複数のアプリケーションをまとめて起動することができます。

Docker runを使って起動すると、それらアプリケーションをオプションを記述しつつ1コマンドづつ実行しますが、Docker Composeを使うと1回のシンプルなコマンド入力でそれらを実行できます。

WordPressが動作する環境を作る

まずMacやWindowsにDocker Desktopをインストールします。(方法はこちらを参照)

Docker DesktopにはDocker Composeが含まれているので、別途インストールする必要はありません。

Docker Composeのバージョンをチェックしてみます。

$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01

バージョン情報が表示されればDocker Composeは使える状態です。

WordPressを動作させるために必要なDockerイメージを確認します。WordPressはDockerのオフィシャルイメージにあります。WordPressのイメージにはPHPとApacheが含まれているので、あとはデータベースのイメージを使います。データベースはここではMySQLを使います。

Docker Composeは用意された定義ファイルに書かれた内容に従ってDockerイメージを取得してコンテナを起動します。つまり、Docker runで指定していたDockerイメージやオプションを定義ファイルにまとめて書いて実行します。なので1回のコマンド実行で複数コンテナを起動できるのですね。

定義ファイルは決められた名前(docker-compose)と拡張子.ymlもしくは.yamlの「docker-compose.yml」ファイルとなります。この定義ファイルをComposeファイルといいますが、ファイル書式にはバージョンがあります。各バージョンごとにDockerエンジンのバージョンに対応しています。公式サイトはこちらです。

*Dockerの情報は日本語訳しているサイトもありますが、最新情報に追従していないので少し古い可能性があります。

ファイルには決められた書式で定義する内容を記述します。テキストエディタで記述しましょう。エンコード形式は特に公式サイトには記述がなかったのですがUTF-8にしておけば大丈夫です。

まずは公式サイトの説明を参考にして定義内容を記述します。そしてWordPressが動作する環境として作業するためのサブフォルダ(ここでは”sample-wp”とします)を作って、そこにdocker-compose.ymlファイルを保存します。

version: '3.3'

services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root-pass
      MYSQL_DATABASE: wordpress
      MYSQL_USER: db-user
      MYSQL_PASSWORD: db-pass

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: db-user
      WORDPRESS_DB_PASSWORD: db-pass
      WORDPRESS_DB_NAME: wordpress
volumes:
   db_data: {}

公式サイト説明

*わかりやすくするために環境変数の値を少し変更しています。

servicesビルドして起動するコンテナを定義します。上記では「db」と「wordpress」のコンテナを定義しています。それぞれコンテナ定義の下に記述されている定義項目はdocker runのオプションに対応しています。
image起動するDockerイメージを定義します。上記では、wordpressは最新ですが、mysqlは5.7を指定します。mysqlを最新にすると認証形式が違うため上記定義では動作しません。最新のmysqlを使うためには以前と同じ認証形式で動作するよう別途設定が必要です。
depends_on依存関係を定義します。上記では、wordpressに依存関係としてdbを設定しているので、wordpressが起動するときはdbの後になります。また停止する時はwordpressが先に停止してその後dbが停止します。この場合dbがwordpressより先に起動する必要があるため明示的に定義しています。
portsホスト側のポートとコンテナ側のポートをマッピングします。上記ではホスト側8000ポートとコンテナ側80ポートをマッピングしているので、ブラウザでwordpressで作成したサイトを閲覧するときは8000ポートを指定します。
restart再起動のポリシーを定義します。デフォルトは"no"です。alwaysはどんな時も再起動します。
environmentそれぞれのサービスにある環境変数を定義します。
・上記では、mysqlは以下を定義しています。
MYSQL_ROOT_PASSWORD: root-pass(rootのパスワード)
MYSQL_DATABASE: wordpress(データベース名)
MYSQL_USER: db-user(ユーザー名)
MYSQL_PASSWORD: db-pass(パスワード)
・wordpressは以下を定義しています。
WORDPRESS_DB_HOST: db:3306(使用するデータベースとポート番号)
WORDPRESS_DB_USER: db-user(使用するDBユーザー名->mysql設定と同じユーザー名)
WORDPRESS_DB_PASSWORD: db-pass(DBパスワード->mysql設定と同じパスワード)
WORDPRESS_DB_NAME: wordpress(データベース名->mysql設定と同じデータベース名)
volumesトップレベルの記述と各サービスレベルの記述があります。
トップレベルに記述されているvolumesは、そこに記述された名前付きvolumesとなり、複数のサービスから参照できるようになります。また、定義されたvolumeは永続的となり明示的に削除されるまでコンテナを削除してもデータが残ります。
上記の例は"db_data"という名前のvolumeをDBサービスのmysqlが自身の領域に割り当てています。このコンテナが削除されても"db_data"という名前のvolumeでデータベースの内容は残ります。
サービスレベルにもvolumesを記述できます。ホスト側とコンテナ側のディレクトリをマウントする定義をします。
指定方法は以下です。
# パスを指定してエンジンにボリュームを作成させる
- /var/lib/mysql
# 絶対パスをマッピングする
- /opt/data:/var/lib/mysql
# Composeファイルからの相対パスをマッピングする
- ./cache:/tmp/cache
# ユーザーhomeからの相対パスをマッピングして、アクセスモードを指定します
- ~/configs:/etc/configs/:ro
# 名前付きボリュームを作成させる
- datavolume:/var/lib/mysql

Composeファイルに記述する各サービス設定はDocker公式サイトにリファレンスがあります。

このComposeファイルの定義でもWordPressは使えるようになります。

上記公式サイトのサンプルはMySQLの定義にユーザー名とパスワードを設定していますが、起動するWordPress環境が開発目的などローカル環境に限定的なものであればMySQLへのアクセスはrootでいいかもしれません。その場合はMySQL定義にユーザー名とパスワードの設定は必要ありません。WordPressの定義のほうにユーザー名とパスワードをrootとそのパスワードにすればいいです。また、MySQL定義にあるデータベース名もWordPress定義にデータベース名が定義されていれば作成されるので必要ありません。

WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: root-pass

docker-compose.ymlファイルを保存したsample-wpフォルダに移動して以下のコマンドで起動します。

$ cd sample-wp
$ docker-compose up -d

起動できたらブラウザを使ってアドレスに「localhost:8000」にアクセスすると WordPressのセットアップ画面が表示されます。

コンテナの状態を見るには以下のコマンドで行います。

$ docker-compose ps
        Name                       Command               State          Ports       
-------------------------------------------------------------------------------------
sample-wp_db_1          docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp
sample-wp_wordpress_1   docker-entrypoint.sh apach ...   Up      0.0.0.0:8000->80/tcp

起動しているとStateはUpになっています。

起動した環境の停止は以下のコマンドで行います。

$ docker-compose down

このコマンドでコンテナを停止・削除を行います。コンテナを停止だけすることはできますが、結局削除すると思うので普段からdownコマンドで停止すればいいかと思います。

停止してもComposeファイルでデータベースの情報は永続化しているので削除されません。

試しにWordPress投稿内容を編集してからdownコマンドを実行してみてください。その後upコマンドで再び起動してブラウザで見てみると編集した内容が残っているかと思います。

作成したデータベースも削除する場合はdownコマンドに以下のオプションを付けて実行します。

$ docker-compose down --volumes

これでデータベースもまとめて削除されます。

WordPress環境を使い易くする

これまでのComposeファイル定義でもWordPressは使えるようになりますが、この環境を使ってテーマやプラグインの開発・学習、ステージング環境として作成した後に本番環境へ移行する前段階として使用するような場合はよりフレキシブルにソースコードやデータを扱えるようにしたいです。

まずそうするためにここから何をすればいいのか整理します。

・WordPress環境にあるテーマやプラグインのファイル群をホスト側で直接扱えるようにする

・WordPress環境とリンクしているデータベースを各種操作できるようにする。(データをエクスポート・インポートなど)

この2つができればおおよそのことができるようになりそうです。これを実現するためにComposeファイルに定義を追加します。

WordPress環境をホスト側にマウント

テーマやプラグインを直接扱えるようにするには、コンテナ側で構築された環境とホスト側のディレクトリをマウントします。データベースのボリュームを永続化したときに定義したvolumesオプションをサービスレベルで使います。

まず作業フォルダ内にWordPressファイル群がマウントされるサブフォルダを作成します。ここでは”html”フォルダを作成します。

sample-wp
├── docker-compose.yml
└── html/

そしてComposeファイルのwordpressサービス配下に以下を定義します。

wordpress:
  volumes:
    - ./html:/var/www/html

これでコンテナを起動したときにホスト側のhtmlフォルダにWordPressファイル群が作成されます。downコマンドで停止しても削除されません。–volumesオプションを付けて停止しても削除されません。

WordPressテーマやプラグインを格納しているwp-contentフォルダだけをマウントしてもいいです。その場合は例えば以下のように定義すればいいかと思います。

volumes:
  - ./wp-content:/var/www/html/wp-content

phpMyAdminを使えるようにする

データベースを操作するのにGUIツールであるphpMyAdminが使えると便利です。そこでComposeファイルに定義して使えるようにします。オフィシャルイメージのphpMyAdminをサービスとしてイメージを取得しコンテナ起動します。以下の定義をComposeファイルに追加します。

phpmyadmin:
  depends_on:
    - db
  image: phpmyadmin/phpmyadmin
  environment:
    PMA_HOST: db
  restart: always
  ports:
    - "8080:80"

環境変数「PMA_HOST」は依存関係のあるデータベースを設定します。この場合はdbとなります。

この定義を含めて起動後にブラウザでlocalhost:8080にアクセスするとphpMyAdminのログイン画面が表示されます。

rootでログインして各種操作を行います。パスワードはMySQLで設定した環境変数MYSQL_ROOT_PASSWORDの値です。

これでWordPress環境のファイルの操作、データベースの操作ができるようになったと思います。

その他

上記のComposeファイル定義でWordPressファイル群やデータベースを自由に操作できるようになったと思います。ここからはいくつか便利な定義を紹介します。必要に応じて試してみてください。

WordPressを複数同時に起動する

これまではWordPressの定義が1つなので起動するWordPressのサイトも1つです。もし同時に複数のWordPressのサイトを作成したい場合は、ComposeファイルにあるWordPressサービスの定義を増やします。ですが、単純に定義内容をコピーして増やしても正常に作成・起動できません。WordPressを複数定義するポイントは以下です。

・マッピングするホスト側のポート番号をそれぞれ異なったものにする

・使用するデータベース名をそれぞれ異なったものにする

・使用するデータベースのユーザー名とパスワードはrootにする

この3つを定義をすればWordPressを複数同時に起動できます。また、WordPress環境をvolumesでマウントしている場合は、それぞれ異なったフォルダにマウントするようにしましょう。参考に以下が複数定義した例です。

version: '3.3'

services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root-pass

  wordpress1:
    depends_on:
      - db
    image: wordpress:latest
    volumes:
      - ./wp1:/var/www/html
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_PASSWORD: root-pass
      WORDPRESS_DB_NAME: wp1-db

  wordpress2:
    depends_on:
      - db
    image: wordpress:latest
    volumes:
      - ./wp2:/var/www/html
    ports:
      - "8888:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_PASSWORD: root-pass
      WORDPRESS_DB_NAME: wp2-db

  phpmyadmin:
    depends_on:
      - db
    image: phpmyadmin/phpmyadmin
    environment:
      PMA_HOST: db
    restart: always
    ports:
      - "8080:80"

volumes:
    db_data: {}

それぞれのサイトにアクセスするときは「localhost:8000」「localhost:8888」となります。

コンテナ名を付ける

Composeファイルに各サービスの定義にコンテナ名を指定できます。指定がない場合は「作業フォルダ名+”_”+サービス名+”_”+数値」で名前が自動生成されます。

コンテナ名を指定するときは各サービス配下に以下の定義を記述します。

wordpress:
  container_name: my-wp-container

サイトアクセスにサブフォルダを付ける

WordPress環境にブラウザでアクセスするときにサブフォルダを指定したいときはworking_dirを使います。例えば「localhost:8000/wp」とサブフォルダでアクセスしたい場合です。

wordpress:
  volumes:
    - ./html:/var/www/html/wp
  working_dir: /var/www/html/wp

環境設定を別ファイルにする

environment設定の項目を別ファイルにすることができます。environmentの代わりにenv_fileを使ってファイルを指定します。

wordpress:
  env_file: .env

この場合は.envファイルに「環境変数=値」の形式で記述します。ユーザー名やパスワードを設定している環境変数をこのように隠しファイルへ保存することもできます。

ファイルは複数指定できます。複数のサービスが同じ環境変数を使うが値が異なる場合などは、ファイルを別々にして設定します。

wordpress1:
  env_file:
    - ./common.env
    - ./wps/wp1.env
wordpress2:
  env_file:
    - ./common.env
    - ./wps/wp2.env

ファイルは定義した上から順番に反映されます。もし同じ環境変数が別々のファイルに書かれていた場合、後に読み込まれたものが上書きするので最後に読み込まれたものが有効になります。

また、ファイル内にはコメントを記述することができます。「#」文字は1行コメントとして認識されます。そして空白行は無視されます。

# wp1で利用するデータベース名を設定
WORDPRESS_DB_NAME: wp1-db

まとめ

WordPressのテーマやプラグインの開発環境はこれでかなり快適なものが用意できます。必要に応じてComposeファイル定義内容を調整して、その都度環境を起動・停止・削除の操作が簡単にできるのでとても便利です。どうぞDockerライフを楽しんでください。