WordPress docker
クィックスタート: Compose と WordPress に従って docker-compose.yml
を作成
構成
/root
|- /docker
| |- /database
|- /app
| |- /public
|- .env
|- docker-compose.yml
.env
TZ=UTC
DB_DATABASE=wordpress
DB_USER=wordpress
DB_PASSWORD=secret
DB_ROOT_PASSWORD=root
docker-compose.yml
phpmyadmin のコンテナを追加する
version: '3'
services:
mysql:
image: mysql:5.7
volumes:
# データの永続化
- ./docker/database/data:/var/lib/mysql
- ./docker/database/log:/var/log/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
ports:
- 8888:80
depends_on:
- mysql
wordpress:
depends_on:
- mysql
image: wordpress:6.0.1-php8.1
ports:
- "8000:80"
restart: always
volumes:
- ./app/public:/var/www/html
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER: ${DB_USER}
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
volumes:
./docker/database/data:
WordPress をサブディレクトリにインストールする
公開ディレクトリ直下に WordPress のファイルが散らばっているのがあまり好きではないので、サブディレクトリに WordPress をインストールして下記のような構成しにしたい
/root
|- /docker
| |- /database
|- /app
| |- /public
| |- /my-wordpress # WordPress core
| |- index.php
| |- .htaccess
|- .env
|- docker-compose.yml
working_dir
を追加するとそこに WordPress core がインストールされる
docker-compose.yml
wordpress:
depends_on:
- mysql
image: wordpress:6.0.1-php8.1
ports:
- "8000:80"
restart: always
volumes:
- ./app/public:/var/www/html
+ working_dir: /var/www/html/${WORDPRESS_DIR}
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER: ${DB_USER}
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
これで docker compose up
すると /app/publlic/{WORDPRESS_DIR}
内に wordpress のファイルがインストールされる
cf
index.php, .htaccess を移動させる
先の状態のままだと /{WORDPRESS_DIR}
が WordPress の root になってしまうので WordPress のサイトの設定を /
をルートに変更した上で index.php
, .htaccess
を移動させる必要がある
方針
- WP-CLI で WordPress をインストールして
一般設定 > サイトアドレス (URL)
を/
に変更 -
index.php
,.htaccess
を/
に移動させる -
index.php
のrequire __DIR__ . 'wp-blog-header.php'
のパスを書き換える
WP-CLI の導入
- プロキシコンテナを作成して WP-CLI 用のコンテナを作成する
- Pros
- プロキシコンテナで wordpress, mysql などのコンテナを接続できるので wordpress コンテナから mysql コマンド・
wp db check
で mysql コンテナの DB にアクセスが可能
- プロキシコンテナで wordpress, mysql などのコンテナを接続できるので wordpress コンテナから mysql コマンド・
- Cons
- プロキシコンテナを別途起動する必要がある
- wordpress コンテナ内に wp-cli をインストールする
- Pros
- 別途コンテナを起動する必要がない
- Cons
- wordpress コンテナから
mysql
コマンド・wp db check
で mysql コンテナにアクセスできない
- wordpress コンテナから
=> 私のマシンが docker 立ち上げていると激重になってしまうので別途プロキシコンテナを起動するのがキツそうだったので WordPress のコンテナに wp-cli をインストールする方法を選択します
WP-CLI を WordPress コンテナにインストール
WordPress のコンテナをカスタマイズするので Dockerfile を用意する
/root
|- /docker
| |- /database
+| |- /wordpress
+| |- Dockerfile
|- /app
| |- /public
| |- /my-wordpress # WordPress core
| |- index.php
| |- .htaccess
|- .env
|- docker-compose.yml
docker-compose.yml
wordpress:
depends_on:
- mysql
- image: wordpress:6.0.1-php8.1
+ build:
+ context: "./docker/wordpress"
+ dockerfile: "Dockerfile"
+ # Dockerfile に渡す変数を arg で定義する
+ args:
+ - WORDPRESS_DIR=${WORDPRESS_DIR}
ports:
- "8000:80"
restart: always
volumes:
- ./app/public:/var/www/html
working_dir: /var/www/html/${WORDPRESS_DIR}
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER: ${DB_USER}
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
/docker/wordpress/Dockerfile
FROM wordpress:6.0.1-php8.1
# docker-compose.yml の args で定義された変数を `ARG 変数名` とすることで変数として使えるようになる
ARG WORDPRESS_DIR
WORKDIR /var/www/html/${WORDPRESS_DIR}
# Install WP-CLI
RUN 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 \
&& wp --info
👇 動作確認
$ docker compose build
$ docker compose up -d
# wp コマンドは --allow-root を付けないとうまく動作しない
$ docker compose exec wordpress wp help --allow-root
$ docker compose exec wordpress wp --info --allow-root
help, status が表示されていれば OK
WP-CLI で WordPress をインストールする
- コマンドを
setup.sh
として作成 - wordpress コンテナでコマンドを実行
./docker/wordpress/scripts/setup.sh
# WordPressのインストール
#=======================
wp core install \
--url="$WP_HOST_URL/$WORDPRESS_DIR" \
--title="$WP_TITLE" \
--admin_user="$WP_ADMIN" \
--admin_password="$WP_ADMIN_PASSWORD" \
--admin_email="$WP_ADMIN_EMAIL" \
--allow-root
# 一般設定
# =======================
# サイトのアドレス(WordPress)
wp option update --allow-root home $WORDPRESS_DIR/${WORDPRESS_DIR}
# サイトのアドレス(URL)
wp option update --allow-root siteurl $WORDPRESS_DIR
# index.php と .htaccess を移動させる
if [ -e /var/www/html/${WORDPRESS_DIR}/index.php ] && [ -e /var/www/html/${WORDPRESS_DIR}/.htaccess ] && [ ! -e /var/www/html/index.php ] && [ ! -e /var/www/html/.htaccess ]; then
cp /var/www/html/${WORDPRESS_DIR}/.htaccess /var/www/html/.htaccess
cp /var/www/html/${WORDPRESS_DIR}/index.php /var/www/html/index.php
# 元のファイルを ${WORDPRESS_DIR}/tmp に移動
mv /var/www/html/${WORDPRESS_DIR}/.htaccess /var/www/html/${WORDPRESS_DIR}/tmp/.htaccess
mv /var/www/html/${WORDPRESS_DIR}/index.php /var/www/html/${WORDPRESS_DIR}/tmp/index.php
# wp-blog-header.php のインポートパスを修正
sed -i -e "s/\/wp-blog-header\.php/\/$WORDPRESS_DIR\/wp-blog-header.php/g" /var/www/html/index.php
fi
setup.sh
をコンテナにマウント・必要な環境変数を追加
docker-compose.yml
wordpress:
depends_on:
- mysql
build:
context: "./docker/wordpress"
dockerfile: "Dockerfile"
# Dockerfile に渡す変数を arg で定義する
args:
- WORDPRESS_DIR=${WORDPRESS_DIR}
ports:
- "8000:80"
restart: always
volumes:
- ./app/public:/var/www/html
+ - ./docker/wordpress/scripts:/tmp
working_dir: /var/www/html/${WORDPRESS_DIR}
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER: ${DB_USER}
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
+ WORDPRESS_DIR: ${WORDPRESS_DIR}
+ WP_HOST_URL: http://localhost:8000
+ WP_TITLE: ${WP_TITLE}
+ WP_ADMIN_PASSWORD: ${WP_ADMIN_PASSWORD}
+ WP_ADMIN_EMAIL: ${WP_ADMIN_EMAIL}
👇 実行
$ docker compose build
$ docker compose up -d
# コンテナが起動しても WordPress のファイルのインストールは非同期なので WordPress のファイルが全て揃うまで待つ。待たず setup.sh を実行するとエラーになる
$ docker compose exec wordpress chmod +x /tmp/setup.sh
$ docker compose exec wordpress sh /tmp/setup.sh
コマンドがエラーなくじっこうされ localhost:8000
にアクセスして WordPress のサイトが表示されていれば OK
cf.
wordpress コンテナから mysql の接続テストができるようにする
プロキシコンテナ無しでも wordpress コンテナに MySQL クライアントをインストールすればコンテナから mysql
コマンド, wp db
コマンドが実行できるようになるっぽい
/docker/wordpress/Dockerfile
FROM wordpress:6.0.1-php8.1
ARG WORDPRESS_DIR
WORKDIR /var/www/html/${WORDPRESS_DIR}
+ # Install MySQL client
+ RUN apt-get update && apt-get install -y sudo less default-mysql-client
# Install WP-CLI
RUN 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 \
&& wp --info
:warning: mysql-client
だとインストールできない。default-mysql-client
にする必要があった
👇 動作確認
$ docker compose build
$ docker compose up -d
$ docker compose exec wordpress wp db check --allow-root
wordpress.wp_commentmeta OK
wordpress.wp_comments OK
wordpress.wp_links OK
wordpress.wp_options OK
wordpress.wp_postmeta OK
wordpress.wp_posts OK
wordpress.wp_term_relationships OK
wordpress.wp_term_taxonomy OK
wordpress.wp_termmeta OK
wordpress.wp_terms OK
wordpress.wp_usermeta OK
wordpress.wp_users OK
Success: Database checked.
wordpress コンテナから db へのアクセスコマンドが通っていれば OK
cf.
database への接続が確立されるまで処理を止める
wp db check
で WordPress のデータベースに接続できるかが確認できる。
./docker/wordpress/setup.sh
+ echo 'Wating to connect MySQL.'
+ while ! wp db check --allow-root;
+ do
+ >&2 echo -n "."
+ sleep 1
+ done
+ echo 'Connect!';
# WordPressのインストール
#=======================
Database の接続まで処理を止められるが docker compose up
直後に実行すると WordPress のファイルが揃う前に Database への接続が可能になってしまうと引き続きエラーが起きてしまうので、WordPress のファイルが揃うのを確認して実行する必要があるのが問題…
WordPress のファイルが存在するまで処理を待つようにする
⚠
- 非同期でファイルが降りてくるので、どのファイルがあれば完了しているのかを判断するのは難しい
- 一旦
wp-config.php
で存在確認する
./docker/wordpress/setup.sh
echo 'Wating to connect MySQL.'
while ! wp db check --allow-root;
do
>&2 echo -n "."
sleep 1
done
echo 'Connect!';
+ echo "'/${WORDPRESS_DIR}/wp-config.php' の存在確認"
+ # 100回施行する
+ TRYCOUNT=100
+ while [ ! -f /var/www/html/${WORDPRESS_DIR}/wp-config.php ]
+ do
+ if [ $TRYCOUNT -le 0 ]; then
+ echo "WordPress のファイルインストール完了後に再試行してください"
+ exit 0
+ fi
+ >&2 echo -n "."
+ TRYCOUNT=`expr $TRYCOUNT - 1`
+ sleep 3s
+ done
# WordPressのインストール
#=======================
⚠ wp-config.php
があればエラーになる可能性は低いが、WordPress のファイルダウンロードが間に合ってないとエラーになる場合がある。ダウンロードがコンテナ起動後に非同期で行われるので、確実に全て存在するかを確認するのは難しそう…
cf.