目次

Docker Compose で WordPress を構築するチュートリアル:MySQL との連携

この節では、Docker Compose を使って WordPress サイト一式を構築します。完了すると、次の構成になります。

  • WordPress(PHP + Apache、公式イメージ wordpress:7-apache)
  • ヘルスチェック付きの MySQL 8.4 データベース。データベースの準備ができてから WordPress を起動します
  • データは Volume に保存されるため、コンテナを削除して再作成しても失われません
  • ファイルのアップロードサイズを 64 MB に設定
  • 必要なときだけ起動する phpMyAdmin 管理画面

この節で使う Compose の構文(depends_on、healthcheck、profiles、.env)は、Compose 入門 と docker compose コマンド で紹介しました。

プロジェクトを作成する

wordpress フォルダーを作成し、次の 3 つのファイルを配置します。

wordpress/
├── compose.yaml
├── .env
└── uploads.ini

.env:パスワード

MYSQL_ROOT_PASSWORD=change-this-root-password
MYSQL_PASSWORD=change-this-wp-password

自分用のパスワードに置き換えてください。Compose は同じフォルダーにある .env を自動的に読み込み、compose.yaml 内の ${MYSQL_PASSWORD} などの変数をこのファイルの値に置き換えます。.env を Git にコミットしないでください。

uploads.ini:アップロードサイズ

WordPress イメージの PHP アップロード上限はデフォルトで 2 MB しかないため、大きめの画像やテーマをアップロードすると失敗します。ini ファイルで上書きします。

upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M

公式 PHP イメージは /usr/local/etc/php/conf.d/ 以下のすべての .ini ファイルを読み込むため、このファイルをマウントするだけで設定できます。

compose.yaml

services:
  db:
    image: mysql:8.4
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    volumes:
      - db_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-uroot", "-p${MYSQL_ROOT_PASSWORD}"]
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 30s
    restart: unless-stopped

  wordpress:
    image: wordpress:7-apache
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD}
    volumes:
      - wp_data:/var/www/html
      - ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini:ro
    restart: unless-stopped

  phpmyadmin:
    image: phpmyadmin
    depends_on:
      - db
    ports:
      - "127.0.0.1:8081:80"
    environment:
      PMA_HOST: db
    profiles: [tools]

volumes:
  db_data:
  wp_data:

設定のポイント:

設定役割
MYSQL_DATABASE / MYSQL_USER / MYSQL_PASSWORDMySQL イメージの初回起動時(データ用フォルダーが空の場合)に、データベースとアカウントを自動作成します
healthcheck10 秒ごとに mysqladmin ping で MySQL に接続できるか確認します。初期化が完了する前に healthy と判定されてしまうため、localhost ではなく -h 127.0.0.1 を指定してください。理由は MySQL を参照してください
condition: service_healthydb が healthy になってから WordPress を起動し、WordPress が先に起動してデータベースに接続できなくなるのを防ぎます
WORDPRESS_DB_HOST: dbサービス名 db で接続します。Compose のネットワークが MySQL コンテナの IP に自動解決します
db_data:/var/lib/mysqlMySQL のデータを Volume に保存します
wp_data:/var/www/htmlWordPress のプログラム、プラグイン、テーマ、アップロードしたメディアを Volume に保存します
profiles: [tools]phpMyAdmin はデフォルトでは起動せず、--profile tools を付けると起動します
127.0.0.1:8081:80phpMyAdmin をローカルにのみバインドするため、外部から接続できません

MySQL は Compose の内部ネットワークで WordPress からのみアクセスするため、db には ports を設定せず、外部に公開しません。

起動

wordpress フォルダで実行します。

$ docker compose up -d
[+] up 32/32
 ✔ Image wordpress:7-apache        Pulled                                                                                                        28.0s
 ✔ Network wordpress_default       Created                                                                                                        0.1s
 ✔ Volume wordpress_db_data        Created                                                                                                        0.0s
 ✔ Volume wordpress_wp_data        Created                                                                                                        0.0s
 ✔ Container wordpress-db-1        Healthy                                                                                                       11.1s
 ✔ Container wordpress-wordpress-1 Started                                                                                                       11.3s

順序に注目してください。Compose はまずネットワークと 2 つの Volume を作成します。wordpress-db-1 が 11 秒待って Healthy になった後で、wordpress-wordpress-1 が Started になります。これが condition: service_healthy の効果です。初回の実行ではイメージをダウンロードするため、時間がかかります。

状態を確認します。

$ docker compose ps
NAME                    IMAGE                COMMAND                  SERVICE     CREATED          STATUS                    PORTS
wordpress-db-1          mysql:8.4            "docker-entrypoint.s…"   db          16 seconds ago   Up 16 seconds (healthy)   3306/tcp, 33060/tcp
wordpress-wordpress-1   wordpress:7-apache   "docker-entrypoint.s…"   wordpress   16 seconds ago   Up 5 seconds              0.0.0.0:8080->80/tcp, [::]:8080->80/tcp

db の STATUS は (healthy) と表示され、PORTS はコンテナ内部の 3306/tcp のみで、ホストには公開されていません。一方、wordpress はホストの 8080 をコンテナの 80 に割り当てています。

2 つの Volume も作成されました。名前は「プロジェクト名_Volume 名」で、プロジェクト名はデフォルトでフォルダ名になります。

$ docker volume ls
DRIVER    VOLUME NAME
local     wordpress_db_data
local     wordpress_wp_data

ブラウザーでインストールを完了する

http://localhost:8080 を開くと、最初の画面で言語を選択します。一覧から管理画面で使う言語(例:「日本語」)を選び、Continue をクリックします。このチュートリアルのスクリーンショットでは、他の言語版と共用するため、English (United States) を選択しています。

次に、サイト情報を入力します。

WordPress のインストール画面:サイトタイトル、ユーザー名、パスワード、メールアドレスを入力
インストール画面:Site Title、Username、Password、Your Email を入力し、最後に Install WordPress をクリック
項目説明
Site Titleサイトのタイトルです。後から管理画面で変更できます
Username管理者アカウントです。推測されやすいため admin は使わないでください(この例では説明のために使用しています)
Password管理者パスワードです。WordPress が強度を表示します
Your Email管理者のメールアドレスです。通知の受信とパスワードのリセットに使います
Search engine visibilityチェックすると、検索エンジンにインデックスしないよう求めます。サイトのテスト中はチェックできます

ここではデータベース設定画面は表示されません。WORDPRESS_DB_* 環境変数で接続情報が指定されており、イメージの起動時に wp-config.php が自動生成されるためです。

Install WordPress をクリックし、Success 画面が表示されたらインストール完了です。

WordPress のインストール成功画面
インストール成功。Log In をクリックしてログインページに進みます
WordPress のログインページ
ログインページ http://localhost:8080/wp-login.php

先ほど設定したユーザー名とパスワードでログインすると、管理画面が表示されます。ウェルカム欄に表示されるバージョンは 7.1.3 です。これは wordpress:7-apache イメージにその時点で含まれているバージョンです。

WordPress 7.1.3 の管理画面
WordPress 管理画面(Dashboard)

フロントエンドの http://localhost:8080 には、デフォルトの Hello world! の投稿が表示されます。

WordPress サイトのフロントエンド
サイトのフロントエンド(ログイン中は上部に管理ツールバーが表示されます)

アップロードサイズの上限を確認する

管理画面で Media → Add Media File を開くと、アップロード領域の下に現在の上限が表示されます。Maximum upload file size: 64 MB と表示されていれば、uploads.ini が適用されています。

WordPress のアップロード画面に Maximum upload file size: 64 MB と表示
Upload Media ページの下部に上限 64 MB と表示されています

まだ 2 MB の場合は、uploads.ini のマウントパスが正しいか確認してください。変更後は docker compose up -d でコンテナを再作成する必要があります(restart では新しい設定は適用されません)。

phpMyAdmin でデータベースを管理する(任意)

phpMyAdmin には profiles: [tools] が設定されているため、通常の docker compose up -d では起動しません。必要なときは --profile tools を追加します。

$ docker compose --profile tools up -d phpmyadmin
[+] up 25/25
 ✔ Image phpmyadmin                 Pulled                                                      6.3s
 ✔ Container wordpress-db-1         Running                                                     0.0s
 ✔ Container wordpress-phpmyadmin-1 Started                                                     0.6s

コマンドの最後に phpmyadmin を指定しているため、それと依存先の db(すでに実行中)だけが起動します。

http://localhost:8081 を開き、Username に root、Password に .env 内の MYSQL_ROOT_PASSWORD を入力します。

phpMyAdmin のログイン画面
phpMyAdmin のログイン画面。サーバーは PMA_HOST で db に指定されています

ログインしたら、左側の wordpress データベースをクリックすると、WordPress が作成した 12 個のテーブル(wp_posts、wp_options、wp_users…)が表示されます。

phpMyAdmin に表示された wordpress データベースのテーブル
wordpress データベースのテーブル

phpMyAdmin のポートは 127.0.0.1 にバインドされているため、ローカルからのみ接続できます。リモートサーバーの場合は、SSH トンネル(ssh -L 8081:127.0.0.1:8081 使用者@サーバー)経由で接続し、インターネットに公開しないでください。使い終わったら、phpMyAdmin だけを停止できます。

docker compose --profile tools stop phpmyadmin

データの保存場所

Volume内容
wordpress_db_dataMySQL データベース:投稿、ページ、設定、ユーザー、コメント
wordpress_wp_dataWordPress のプログラム、テーマ、プラグイン、アップロードしたメディア(wp-content/uploads)

どちらもバックアップが必要です。片方だけではサイトを完全に復元できません。

バックアップ

プロジェクトフォルダーで実行します。最初に mysqldump でデータベースをエクスポートし、次に一時的な alpine コンテナを使って wp_data Volume を tar.gz にまとめます。

$ docker compose exec -T db sh -c 'mysqldump -uroot -p"$MYSQL_ROOT_PASSWORD" wordpress' > wordpress.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.

$ ls -lh wordpress.sql && head -n 5 wordpress.sql
-rw-r--r--    1 root     root      880.8K Oct 13 00:22 wordpress.sql
-- MySQL dump 10.13  Distrib 8.4.11, for Linux (x86_64)
--
-- Host: localhost    Database: wordpress
-- ------------------------------------------------------
-- Server version	8.4.11

$ docker run --rm -v "$(basename "$PWD")_wp_data:/data:ro" -v "$PWD:/backup" alpine:3.23 tar czf /backup/wp_data.tar.gz -C /data .

$ ls -lh wp_data.tar.gz
-rw-r--r--    1 root     root       33.9M Oct 13 00:22 wp_data.tar.gz

説明:

  • exec -T:TTY を無効にすることで、出力を > でファイルに正しくリダイレクトできます。
  • sh -c '... -p"$MYSQL_ROOT_PASSWORD"':変数がコンテナ内で展開されるように、シングルクォートを使います(MySQL コンテナにはこの環境変数があります)。ホスト側でパスワードを知る必要はありません。
  • [Warning] Using a password on the command line interface can be insecure. は MySQL の警告で、stderr に出力され、wordpress.sql には含まれないため無視できます。
  • wordpress.sql の先頭に MySQL dump … Distrib 8.4.11 とあれば、エクスポートは成功しています。
  • $(basename "$PWD")_wp_data から Volume 名 wordpress_wp_data が組み立てられます。フォルダー名が異なる場合は、docker volume ls で確認してください。
  • :ro は読み取り専用でのマウントを意味し、バックアップ中にデータが変更されません。

wordpress.sql と wp_data.tar.gz を別のマシンまたはクラウドストレージにコピーして、初めてバックアップが完了します。

Windows ユーザー向けのバックアップ

PowerShell は < をサポートしておらず、Windows PowerShell 5.1 の > は SQL ファイルを UTF-16 で保存します。コンテナ内でファイルを作成してから docker compose cp でコピーしてください。wp_data をアーカイブするときは Volume 名を直接指定します(デフォルトは フォルダー名_wp_data)。

docker compose exec db sh -c 'mysqldump -uroot -p$MYSQL_ROOT_PASSWORD --result-file=/tmp/wordpress.sql wordpress'
docker compose cp db:/tmp/wordpress.sql wordpress.sql
docker run --rm -v wordpress_wp_data:/data:ro -v "$(pwd):/backup" alpine:3.23 tar czf /backup/wp_data.tar.gz -C /data .
docker compose exec db sh -c 'mysqldump -uroot -p$MYSQL_ROOT_PASSWORD --result-file=/tmp/wordpress.sql wordpress'
docker compose cp db:/tmp/wordpress.sql wordpress.sql
docker run --rm -v wordpress_wp_data:/data:ro -v "${PWD}:/backup" alpine:3.23 tar czf /backup/wp_data.tar.gz -C /data .
docker compose exec db sh -c "mysqldump -uroot -p$MYSQL_ROOT_PASSWORD --result-file=/tmp/wordpress.sql wordpress"
docker compose cp db:/tmp/wordpress.sql wordpress.sql
docker run --rm -v wordpress_wp_data:/data:ro -v "%cd%:/backup" alpine:3.23 tar czf /backup/wp_data.tar.gz -C /data .

復元するときは逆の手順です。docker compose cp wordpress.sql db:/tmp/restore.sql を実行し、その後 docker compose exec db sh -c 'mysql -uroot -p$MYSQL_ROOT_PASSWORD wordpress < /tmp/restore.sql' を実行します。tar のアーカイブと展開はどちらも alpine コンテナ内で行うため、Windows の影響を受けません。

復元

新しいマシン(または初期化後)に compose.yaml、.env、uploads.ini と 2 つのバックアップファイルを配置してから、次を実行します。

# 1. 只啟動資料庫,等它 healthy
docker compose up -d --wait db

# 2. 匯入資料庫
docker compose exec -T db sh -c 'mysql -uroot -p"$MYSQL_ROOT_PASSWORD" wordpress' < wordpress.sql

# 3. 還原 WordPress 檔案到 Volume
docker run --rm \
  -v "$(basename "$PWD")_wp_data:/data" \
  -v "$PWD:/backup" \
  alpine:3.23 sh -c "cd /data && tar xzf /backup/wp_data.tar.gz"

# 4. 啟動全部服務
docker compose up -d

--wait はサービスが healthy になるまで待ってから戻るため、データベースの準備ができる前にインポートを始めるのを防げます。.env のパスワードはバックアップ時と同じものにしてください。wp_data 内の wp-config.php に古いデータベースパスワードが記録されているためです。

更新

WordPress コア、テーマ、プラグインは管理画面から直接更新でき、ファイルは wp_data Volume に書き込まれます。

イメージ自体(PHP、Apache、MySQL のマイナーバージョン)を更新するには、次のようにします。

$ docker compose pull
[+] pull 2/2
 ✔ Image wordpress:7-apache Pulled                                                              0.6s
 ✔ Image mysql:8.4          Pulled                                                              0.7s

$ docker compose up -d
[+] up 2/2
 ✔ Container wordpress-wordpress-1 Running                                                      0.0s
 ✔ Container wordpress-db-1        Healthy                                                      0.5s

pull は新しいイメージをダウンロードします。up -d はイメージに変更があるコンテナだけを再作成します。上の例ではイメージに新しいバージョンがないため、コンテナは Running のままです。

注意事項:

  • 更新前にバックアップしてください。
  • wordpress:7-apache は 7.x に追従して更新されます。バージョンを固定する場合は、wordpress:7.1.3-apache のように完全なバージョン番号を指定してください。
  • wp_data にすでに WordPress のファイルがある場合、イメージで上書きされません。そのため、WordPress コアのバージョンは管理画面での更新に従います。
  • MySQL のメジャーバージョンをまたいで更新する場合(例:8.0 → 8.4)は、先に MySQL 公式のアップグレード手順を確認してください。タグを直接変更しないでください。

環境全体を削除する

練習後に環境を削除するには、--profile tools を付けると phpMyAdmin も一緒に削除されます。-v は Volume を削除するため、サイトのデータはすべて消えます。

$ docker compose --profile tools down -v
[+] down 6/6
 ✔ Container wordpress-wordpress-1  Removed                                                     1.5s
 ✔ Container wordpress-phpmyadmin-1 Removed                                                     1.5s
 ✔ Container wordpress-db-1         Removed                                                     2.3s
 ✔ Volume wordpress_wp_data         Removed                                                     0.3s
 ✔ Network wordpress_default        Removed                                                     0.2s
 ✔ Volume wordpress_db_data         Removed                                                     0.3s

本番環境への公開に関する注意事項

  • 手前にリバースプロキシを配置して HTTPS を処理します。Nginx、Caddy、Traefik などを利用できます。Nginx の静的サイトとリバースプロキシを参照してください。
  • データベースを ports で外部公開しないでください。phpMyAdmin をパブリックインターネットに公開しないでください。
  • 管理者アカウントに admin を使わず、十分に強力なパスワードを設定してください。
  • 定期的に自動バックアップを行い(例:cron で上記のバックアップコマンドを実行)、バックアップを別のマシンに保存してください。
  • .env を Git にコミットしないでください。

まとめ

  • WordPress と MySQL は Compose で管理し、データはそれぞれ db_data と wp_data の 2 つの Volume に保存します。
  • MySQL のヘルスチェックでは -h 127.0.0.1 を使い、初期化中に healthy と判定されるのを防ぎます。
  • phpMyAdmin は profile に含め、127.0.0.1 のみにバインドします。
  • バックアップにはデータベースとサイトのファイルの両方を含め、別のマシンに保存してください。

練習問題

練習 1:1 つのコマンドで、PHP のアップロード上限が 64M になっていることを確認してください。

解答
docker compose exec wordpress php -r "echo ini_get('upload_max_filesize');"

出力は 64M です。

練習 2:サイトを別のホストに移行するには、どのファイルを持っていく必要がありますか?

解答

compose.yaml、.env、uploads.ini と、2 つのバックアップ wordpress.sql(データベース)および wp_data.tar.gz(サイトのファイル)です。新しいホストで、この章の「復元」の手順に従って操作してください。

よくある質問

インストール画面でデータベース設定を入力する必要がないのはなぜですか?

WORDPRESS_DB_* 環境変数で接続情報がすでに指定されているため、イメージの起動時に wp-config.php が自動的に生成されます。

ファイルをアップロードするとサイズ上限を超えたというエラーが表示されます。

WordPress イメージの PHP アップロード上限はデフォルトで 2 MB です。この章の uploads.ini で変更し、docker compose up -d を実行してコンテナを再作成してください。

Windows でバックアップするにはどうすればよいですか?

PowerShell は < をサポートしておらず、Windows PowerShell 5.1 の > はファイルのエンコードを変更します。この章の「バックアップ」節では、コンテナ内でエクスポートしてから docker cp で取り出す方法を紹介します。

更新日 2026年10月14日