Docker でお手軽 WordPress 練習環境の作り方 - MacBook M1/M2版

feature-image

WordPress の動作テストをしたくなったので、使い捨ての環境を Docker でセットアップしました。

この記事ではあわせて、MacBook M1 チップセットでの Docker 構築についても触れています。2021 年 10 月に発売された MacBook Pro を購入し、巷で噂の Apple M1 チップ(Apple Silicon)にようやくデビューしました。従来の Intel チップで難なく動いていた Docker 環境に少々手間取りましたので記録します。

完成コンフィグ(Docker Compose)

version: "3"

# 開発を目的としたものであり、パスワードは全て脆弱です。本番運用のときには注意をしてください
services:
  db:
    image: mysql:5.7
    # 2022/1 時点、M1チップ(arm64)では mysql は動かないので x86_64 を指定
    platform: linux/x86_64
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: mysql-root-password
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

  wordpress:
    depends_on:
      - db
    image: wordpress:5.8
    ports:
      - "8000:80"
    volumes:
      - ./data:/var/www/html:delegated
      - ./upload_max_filesize.ini:/usr/local/etc/php/conf.d/upload_max_filesize.ini
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
volumes:
  db_data: null

前提

WordPress の動作テスト環境を Docker で構築するメリット

一言で表すとお手軽だからに尽きます。

  • (Docker 実行環境の準備ができていれば)1 分で新規 WordPress 環境を用意できる
  • 壊れても 1 分で再構築が完了するので臆することなく色々な変更にチャレンジができる

「わざわざテスト環境を作らなくても、本番環境で直接やっちゃうよ」という人もいると思います。

本番環境の WordPress でいろいろ試すのもよいですが、デザインの変更が必ずしも 1 回で上手くいくとは限らないし、プラグインを作ったりしているのならばエラーが出てしまったりするでしょう。変更がわけのわからない状態になったら、いっそのこと新規セットアップをしてしまったほうが早いかもしれません。

あるいは、「昔のバージョンではしっかり動いていたのに、バージョンアップしたら動かなくなった。改めて昔のバージョンで試したみたい」というシーンでも、1 分で再セットアップが完了します。

先程から「1 分」と連呼していますが、大げさではなく本当に 1 分で済んでしまうのです。

設定の解説

オフィシャルイメージを利用して構築します。

起動のやり方

冒頭に記載した yamlファイル を、 docker-compose.yml という名前で保存します。

その後、 docker-compose up で実行完了です。

# -d オプションをつけるとバックグラウンドで起動します
wordpress ❯ docker-compose up -d

wordpress ❯ docker-compose ps
NAME                    COMMAND                  SERVICE             STATUS              PORTS
wordpress-db-1          "docker-entrypoint.s…"   db                  running             33060/tcp
wordpress-wordpress-1   "docker-entrypoint.s…"   wordpress           running             0.0.0.0:8000->80/tcp

# 補足: wordpress というディレクトリを作って作業をしているのでコンテナ名の先頭に文字が付与される

DB の設定

  db:
    image: mysql:5.7
		# 2022/1 時点、M1チップ(arm64)では mysql は動かないので x86_64 を指定
    platform: linux/x86_64
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data: null

MySQL 5.7 を指定していますが、複雑なことをせず「とりあえず動かしたい」が目的の場合は MySQL 8 でも Maria DB でも何でもいいと思います。

/var/lib/mysql に MySQL データベースのデータファイルが保存されますので、このディレクトリを永続化します。永続化をすることで、コンテナを再起動してもデータが残って作業を継続できます。

コンテナに不慣れな方は「そんなの当たり前じゃないの?」と思うかもしれませんが、コンテナというのは揮発的なので、基本的にはデータはその場限りで消えるものです。

platform: linux/x86_64 についてもポイントでした。MySQL のイメージは M1 チップセット(arm)では動作しなかったので、Intel アーキテクチャを指定しています。

wordpress ❯ docker-compose up
[+] Running 0/2
 ⠴ wordpress Pulling                                                                                           3.4s
 ⠴ db Pulling                                                                                                  3.4s
no matching manifest for linux/arm64/v8 in the manifest list entries

このようの no matching と出ます。

WordPress の設定

wordpress:
  depends_on:
    - db
  image: wordpress:5.8
  ports:
    - "8000:80"
  volumes:
    - ./data:/var/www/html:delegated
    - ./upload_max_filesize.ini:/usr/local/etc/php/conf.d/upload_max_filesize.ini

この設定の場合は、起動後に http://localhost:8000/ でアクセスできます。

  • /var/www/html に WordPress 関連のデータが配置されます。ここでも DB と同様にデータを永続化するためにマウントしていますが、./data としています。
    • docker-compose.yml が保存されているディレクトリで起動( docker-compose up )することを想定しています。
    • 同ディレクトリの直下に ./data ディレクトリが作成されますが、この中身はコンテナ内部の /var/www/html にマッピングされます。つまり、コンテナ内のデータを ./data ディレクトリから読み書きすることができますので、テーマやプラグインの作成にあたって直接編集して試すことが可能です。
  • ./upload_max_filesize.ini もマウントしていますが、これは何でしょうか?
    • PHP ファイルの設定を変更しています。この WordPress のイメージは、コンテナ内の /usr/local/etc/php/conf.d/ のディレクトリ直下に設定ファイルを配置することで読み込んでくれる仕様になっています。
    • このサンプルでは、以下に示す一行だけが設定されているファイルです。デフォルトではファイルアップロードが 1 ファイルあたり 2MB になっていますので、上限を拡張しています。
upload_max_filesize = 8M

See the “Configuration” section of the php image documentation.
For example, to adjust common php.ini flags like upload_max_filesize, you could create a custom.ini with the desired parameters and place it in the $PHP_INI_DIR/conf.d/ directory:

FROM wordpress:tag
COPY custom.ini $PHP_INI_DIR/conf.d/

設定前(2M)

ファイルアップロードサイズ設定前(2M)

設定後(設定値による。ここでは 8M)

ファイルアップロードサイズ設定後(8M)

volumes で指定している delegated の意味

Docker for Mac は遅いようです。公式にも書かれています。確かに、遅い。

早くする代わりにディスク書き込みの何かを犠牲にする選択肢が以下の通りあります。

  • consistent :完全な一貫性(常にホストとコンテナが完全に同じ表示)
  • cached :ホストの表示が信頼できる(ホスト上の更新がコンテナ上に反映するまで、遅延が発生するのを許容)
  • delegated :コンテナの表示が信頼できる(コンテナ上の更新がホスト上に反映するまで、遅延が発生するのを許容)

delegated  設定では、一連の(一貫性に対する)保証が最も弱いものです。 delegated  でディレクトリをマウントすると、コンテナのファイルシステム上の表示が信頼できるものとなり、コンテナ内での書き込み処理が、ホスト上のファイルシステムに即時反映しない場合があります。NFS 非同期モードのような状況であれば、もしも  delegated  バインドマウントしたコンテナがクラッシュすると、書き込みが失われる可能性があります。
しかしながら、一貫性の放棄により、 delegated  マウントは他の設定に比べて著しいパフォーマンスをもたらします。空っぽのスペースやビルド成果物のような、データの書き込みが一時的(ephemeral)または直ぐに再生成可能であれば、 delegated  は正しい選択になるでしょう。

「ホストの層」「Docker Engine の層」「コンテナの層」としていくつかの階層があるので、これら階層の間でのデータ保証に関する調整と捉えれば概ねよいかと思います。より正確には、HyperKit で調べてください。

HyperKit とは何ですか?
HyperKit は macOS の Hypervisor.framerowk 上に構築されたハイパーバイザです。これは他の依存関係なく、ユーザ空間全体を実行できます。
私たちが HyperKit を採用するのは、 Oracle VirtualBox や VMWare Fusion のような他の仮想マシンプロダクトの必要性を無くすためです。
https://docs.docker.jp/docker-for-mac/faq.html#hyperkit

この環境の WordPress でメディアのアップロードが遅く感じたので改善を試みたのですが、正直なところ指定しなかった場合と delegated の場合とで体感の差を感じられませんでした。定量的には測定していませんがディスク IO が少ない用途でしか使っていませんので、妥当な印象ではあります。

コンパイルなどをするケースでは差が出るとのこと。必要なときがきたらまた試してみることにします。

docker-compose up で起動したあとの設定

http://localhost:8000 にアクセスすると、見慣れたセットアップ画面が出てきます。

設定ファイルをコピペして docker-compose up しただけです。1 分で起動しましたね。

WordPressインストール

WordPressインストール

Docker for Mac のダッシュボード

GUI があると地味に便利です。操作はコマンドでやった方がいいですが、現在の状態をグラフィカルに見ることができるという点では GUI の価値を感じます。MySQL のコンテナ(ここでは wordpress-db-1 )がオレンジ色で amd64 と書かれていますね。

Docker for Mac ダッシュボード

Docker for Mac に関するトラブルの振り返り

以前の MacBook では長いこと Docker の環境を変更していなかったので(シンプルに使えれば十分だった)、現在のようなグラフィカルな Docker for Mac の UI には戸惑いました。また、 M1 に Docker for Mac をセットアップした直後、 docker コマンドが使えなくてかなり困っていました。

結果は何てことのない /usr/local/bin/docker に対して PATH が通っていない自身の環境問題でした。arm と x86 それぞれで環境変数を分岐している部分があり、そこで考慮漏れがありました。

最初は 「M1 版 Docker for Mac では何か特殊なことが起きているのか?」なんて疑ってしまいましたが、灯台下暗しですね。

M1 で Docker が動かなくて困っている場合、もしかしたら PATH の確認漏れかもしれませんよ!

echo $PATH | tr ":" "\n"