ゼロから始めない Docker + WordPress ハンズオン

Docker

概要

コンテナとかハイパーバイザーとか言われてもよくわからない。とりあえず動かしたほうが理解が早まりそうだと考える人のために。

試行錯誤しながらハンズオンで書いてみて手に馴染ませたい! という人へ向けた記事。

VSCode を使ってやっていきます。

動作環境は WSL2 の Ubuntu。以下の記事でセットアップした前提で進んでいきますが、Ubuntu ならだいたい大丈夫なはずです。

WSL2 + Docker + Docker Compose V2 セットアップ

対象読者

  • Docker のことがなんとなくわかってる
  • Docker の環境がある
  • PHP の知識が少しある
  • mkdir, ls, cd などの基本的な Linux コマンドを理解できる

到達目標

  • Docker を使ってWordPress 環境を構築できる

制約

  • Docker Image には以下の2つを使い、WordPress 同梱のものは使用しない
    • php apache 同梱の PHP イメージ
    • mysql 公式イメージ

コンテナの準備

まずは今回のハンズオン用にディレクトリを作成し、その中に入る。

mkdir docker-wordpress cd docker-wordpress

ハンズオン用のディレクトリで VSCode を起動する。(ほかにあればお好みのエディタで)

code .

PHP の Dockerfile を作成する

docker-wordpress ディレクトリに docker ディレクトリ、さらにその中に php ディレクトリを作成し、さらにその中に Dockerfile という名前のファイルを作成する。

docker/php/Dockerfile に以下のような内容を記載する。

FROM php:8.2-apache COPY ./html/ /var/www/html/

FROM には Docker Image の名前やバージョンを指定したりします。

この場合、簡単にいうと PHP v8.2 がすぐ動くサーバーが同梱された Docker Image が使える。

PHP の動作確認

複数のコンテナをいい感じに管理するための設定ファイルである docker-compose.yml を作成する。

docker-compose は本来複数のコンテナを管理するためのものだが、MySQL コンテナに関しては一旦後回しにして、PHP が動くかどうか確認していく。

docker-compose.yml という名前でファイルを作成し、以下の内容を記載する。

version: "3.9" services: web: build: context: . dockerfile: ./docker/php/Dockerfile volumes: - ./html:/var/www/html ports: - 8080:80

適当に PHP ファイルを作る。 html/index.php ファイルを作成する。

<?php echo "Hello World!" ?>

ディレクトリ構成は以下のようになった。

├── docker │   └── php │   └── Dockerfile ├── docker-compose.yml └── html └── index.php

ここで試しに以下のコマンドを叩いて、Docker コンテナの PHP が正しく動作しているか確認する。

docker compose up -d

するとコンテナが起動し、http://localhost:8080 をアクセスしたときに index.php の内容が表示されるようになる。

試しに内容を変えてページを更新してみると、もちろん表示内容が変わる。

<?php echo "Hello Docker!" ?>

動作確認が済んだら、以下のコマンドでコンテナを終了しておく。

docker compose down --remove-orphans

--remove-orphans オプションはなくてもいいのですが、とりあえずつけておくとよいです。

DB コンテナを用意する

PHP の動作確認が済んだので、MySQL がインストールされたコンテナを用意する。

docker/mysql/Dockerfile を作成して以下を記載する。

FROM mysql/mysql-server:8.0

本当はもっと my.cnf を用意してマウントしたり、なんやかんや記述したほうがいいのですが、ここでは最小限にとどめます。

環境変数を管理するために .env ファイルを作る。

DB_PORT=3306 DB_NAME=wordpress_db DB_USER=wordpress_user DB_PASS=wordpress_password

git で管理する場合、.env は .gitignore して git 管理から外すように。

今ディレクトリはこんな感じになった。

├── docker │ ├── mysql │ │ └── Dockerfile │ └── php │ └── Dockerfile ├── .env ├── docker-compose.yml └── html └── index.php

docker-compose.yml を以下のように変更する。

version: "3.9" services: web: build: context: . dockerfile: ./docker/php/Dockerfile volumes: - ./html:/var/www/html ports: - 8080:80 db: build: context: . dockerfile: ./docker/mysql/Dockerfile ports: - 3306:${DB_PORT} volumes: - db-store:/var/lib/mysql environment: - MYSQL_DATABASE=${DB_NAME} - MYSQL_USER=${DB_USER} - MYSQL_PASSWORD=${DB_PASS} - MYSQL_ROOT_PASSWORD=${DB_PASS} volumes: db-store:

.env に記載した内容を ${変数名} のように書くと、コンテナの中の環境変数として持っていくことができる。

この状態でもう一度以下のコマンドを叩くと Docker コンテナがビルドされて再起動する。 ちなみに、Dockerfile や docker-compose.yml のような、Docker に関わるファイルを変更した際には、docker compose build をする必要がある。

docker compose build

その後、もう一度立ち上げてから

docker compose up -d

コンテナを確認してみると、web コンテナと db コンテナの2つが立ち上がっていることが分かる。

docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS docker-wordpress-db-1 docker-wordpress-db "/entrypoint.sh mysqld" db 12 seconds ago Up 11 seconds (health: starting) 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060-33061/tcp docker-wordpress-web-1 docker-wordpress-web "docker-php-entrypoint apache2-foreground" web 12 seconds ago Up 11 seconds 0.0.0.0:8080->80/tcp, :::8080->80/tcp

MySQL の動作確認

一応 DB コンテナのテストもすることにする。

以下のコマンドで DB コンテナの中に入ると、DB コンテナ内の bash が操作できる。

docker compose exec db bash

コンテナの中の bash で、以下のコマンドを叩く。

mysql -u wordpress_user -p

パスワードが要求されるので、先ほど .env に設定した wordpress_password と入力する。

するとこんな感じに mysql のコマンドラインに切り替わった。

Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 10 Server version: 8.0.32 MySQL Community Server - GPL Copyright (c) 2000, 2023, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>

試しに以下のコマンドでデータベース一覧を表示すると、事前に環境変数に入れておいた wordpress_db が作成されていることが分かる。

show databases;
+--------------------+ | Database | +--------------------+ | information_schema | | performance_schema | | wordpress_db | +--------------------+ 3 rows in set (0.01 sec)

Ctrl + D で MySQL コマンドラインやコンテナが出ることができる。

Makefile を作る

そろそろコマンドを叩くのがめんどくさくなってきたので、Makefile を作成する。

Makefile というファイル名のファイルを作成する。

up: docker compose up -d down: docker compose down --remove-orphans web: docker compose exec web bash db: docker compose exec db bash

すると以下のようにコマンドを省略することができる。

docker compose up -d make up

make コマンドを使えるようにするには、以下のコマンドを叩けば OK。

sudo apt-get update sudo apt install build-essential -y

WordPress をインストールする

DB コンテナも用意できたので、WordPress を用意してインストールする

ここでは WordPress 同梱の Docker Image をあえて使っていないので、wget コマンドでインストールすることにする。

が、 この web コンテナは wget コマンドを利用できない。

ということで、docker/php/Dockerfile に wget をインストールするコマンドを追記した。

FROM php:8.2-apache # wget インストール RUN apt update \ && apt install wget COPY ./html/ /var/www/html/

そして Docker に関わるファイルを変更したので、一旦ビルドし直す。

docker compose build

ビルドが済んだら、もう一度コンテナを起動する。さっそく先ほど作成した Makefile で自作したコマンドを使ってみる。

make up

起動した web コンテナに入る。

make web

カレントディレクトリが /var/www/html であることを確認して、先ほどお試しで作った index.php を削除しておく。

rm -f index.php

以下のコマンドを叩いてダウンロード。

wget https://ja.wordpress.org/latest-ja.tar.gz

そして tar コマンドでファイルを展開。

tar -zxvf latest-ja.tar.gz

アーカイブの内容が wordpress ディレクトリという名前で展開されるので、その中身を html 直下に取り出しておきます。

mv ./wordpress/* .

www-data を所有者にしておく。(これはあとで面倒なことになるのでのちほどなかったことにするのですが、こうしておかないと WordPress が動かないので変えておきます)

chown -R www-data:www-data /var/www/html/

最後に、アーカイブと空の wordpress ディレクトリが不要になったので削除する。

rm -rf latest-ja.tar.gz wordpress

この状態で、 http://localhost:8080 にアクセスすると、WordPress の画面が……と言いたいところですが、「mysqli PHP 拡張機能がインストールされ、有効になっていることを確認してください。」というメッセージが表示されています。

なので mysqli PHP 拡張機能というものを有効にします。

docker/php/Dockerfile を以下のように変更してもう一度ビルド。

FROM php:8.2-apache # wget インストール RUN apt update \ && apt install wget # mysql 拡張インストール RUN apt-get update \ && apt-get install -y libpq-dev \ && docker-php-ext-install pdo_mysql pdo_pgsql mysqli COPY ./html/ /var/www/html/
docker compose build
make up

これでもう一度 http://localhost:8080 にアクセスすると、いつものようこそ画面が現れる。

データベース名やらデータベースのユーザ名は、 .env に設定した内容でいいのですが、ホスト名は localhost ではなく、 db と入力します。 docker-compose.yml に記載してある service 名が db であり、ホスト名として使われるからです。

インストールが終わってユーザー登録が完了すると、ダッシュボードへ入ることができた。

パーミッションの修正

実はこの状態だと、VSCode 側からの編集が不可能になっている。

www-data というユーザがファイルの所有権をもっていて、パソコンの利用者である僕たちに書き込み権限がない。

ただこの www-data にも読み書き権限を与えておかないと、WordPress のインストールもできないし、プラグインを入れたりすることもできない。

なので先ほど www-data に chown コマンドで所有権を移した。

これを「WordPress での操作も支障がなくて、エディターからの操作に支障がない」という状態にする。

まず、自分の PC ユーザーの ID を確認する。

Docker コンテナから出た状態で、以下のコマンドを叩く。

id $USER

すると自分のユーザーの uid,gid,groups が確認できる。たいていの場合、uid は 1000 だと思うので、1000という前提で進めていく。

一旦コンテナを終了しておく。

make down

ホストマシン上で、再帰的にファイルの所有者を自分に戻す。

sudo chown -R $USER:$USER html

docker/php/Dockerfile を以下のように編集する

FROM php:8.2-apache ARG uid ARG gid ENV username=coder # ユーザー作成して、 www-data を coder のグループに追加する RUN groupadd -g $gid $username \ && useradd -u $uid -g $username -s /bin/bash $username \ && gpasswd -a www-data $username # wget インストール RUN apt update \ && apt install wget # mysql 拡張インストール RUN apt-get update \ && apt-get install -y libpq-dev \ && docker-php-ext-install pdo_mysql pdo_pgsql mysqli COPY ./html/ /var/www/html/ # ディレクトリおよびファイルの所属グループに読み書きと実行の権限を与え # 所有者を coder にする RUN chmod -R 774 /var/www/html/ \ && chown -R $username:$username /var/www/html/ # コンテナを coder として起動する USER $username

.env に以下を追記する。

UID=1000

docker-compose.yml を以下のように変更する。

version: "3.9" services: web: build: context: . args: uid: ${UID} gid: ${UID} dockerfile: ./docker/php/Dockerfile volumes: - ./html:/var/www/html ports: - 8080:80 db: build: context: . dockerfile: ./docker/mysql/Dockerfile ports: - 3306:${DB_PORT} volumes: - db-store:/var/lib/mysql environment: - MYSQL_DATABASE=${DB_NAME} - MYSQL_USER=${DB_USER} - MYSQL_PASSWORD=${DB_PASS} - MYSQL_ROOT_PASSWORD=${DB_PASS} volumes: db-store:

再度ビルドして立ち上げ直す。

docker compose build make up

これでエディターからも編集することができ、WordPress ダッシュボード上からプラグインを入れたり、メディアをアップロードしたりすることもできるようになる。

試しに以下のコマンドで web コンテナに入り、所有者と所属グループを確認してみると、こんな感じ。

make web
ls -la

これで

  • ホストマシンで編集している僕らと coder の UID が同じなのでコンテナ内部でも同じ扱いになる
  • www-data はこのグループに所属している
  • coder グループに所属している人が実行も読み書きも変更もできる。

という条件が整って、やりたいことが完了した。

ただ、パーミッションの管理がずさんだと、思わぬ攻撃を受ける可能性がある。

今回はあくまで「開発環境」なので、セキュリティリスクはまったく考慮していないということをご承知ください。

広告

関連記事

新着記事

広告

Docker + React + Go API 通信できる環境を構築する
WSL2 + Docker + Docker Compose V2 セットアップ