Open6

WordPress docker

KiKiKi-KiKiKiKiKi-KiKi

クィックスタート: 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:
KiKiKi-KiKiKiKiKi-KiKi

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

KiKiKi-KiKiKiKiKi-KiKi

index.php, .htaccess を移動させる

先の状態のままだと /{WORDPRESS_DIR} が WordPress の root になってしまうので WordPress のサイトの設定を / をルートに変更した上で index.php, .htaccess を移動させる必要がある

方針

  1. WP-CLI で WordPress をインストールして 一般設定 > サイトアドレス (URL)/ に変更
  2. index.php, .htaccess/ に移動させる
  3. index.phprequire __DIR__ . 'wp-blog-header.php' のパスを書き換える

WP-CLI の導入

  1. プロキシコンテナを作成して WP-CLI 用のコンテナを作成する
  • Pros
    • プロキシコンテナで wordpress, mysql などのコンテナを接続できるので wordpress コンテナから mysql コマンド・wp db check で mysql コンテナの DB にアクセスが可能
  • Cons
    • プロキシコンテナを別途起動する必要がある
  1. wordpress コンテナ内に wp-cli をインストールする
  • Pros
    • 別途コンテナを起動する必要がない
  • Cons
    • wordpress コンテナから mysql コマンド・wp db check で mysql コンテナにアクセスできない

=> 私のマシンが 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 をインストールする

  1. コマンドを setup.sh として作成
  2. 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.

KiKiKi-KiKiKiKiKi-KiKi

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.

KiKiKi-KiKiKiKiKi-KiKi

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 のファイルが揃うのを確認して実行する必要があるのが問題…

KiKiKi-KiKiKiKiKi-KiKi

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.