DockerのローカルWordPressが遅い原因は?Windowsのbind mountを見直して高速化する

当ページのリンクには広告が含まれています。
Windowsのbind mountによるWordPressの遅延とnamed volumeへの変更による高速化を示した図

以前、以下の記事でDockerを使ったローカルのWordPress環境を構築しました。

この環境を使っていたところ、管理画面だけでなくフロントページも表示が遅くなっていました。実際に応答時間を測定すると、WordPressトップページのHTMLが返ってくるまで約4.5秒かかっています。

いろいろ確認してみた結果、OPcacheやPHPそのものではなくWindows側のWordPress一式をDockerコンテナへbind mountしていた構成が大きく影響していました。

WordPress一式をnamed volumeへ置いた段階では応答時間が約100msまで短縮しました。その後、テーマやプラグインなどをWindows側からbind mountした最終構成では約1.3~1.5秒となり、変更前の約4.5秒より速い状態を維持できています。

この記事では、原因を切り分けた手順と、既存のWordPress環境をできるだけ維持したまま構成を変更した方法をまとめます。

検証環境(確認日:2026年8月)
OS

Windows 11 Home 25H2

Docker

Docker Desktop 4.87.0

WordPress

7.1

PHP

8.5.4

MariaDB

10.5.29-MariaDB-ubu2004

目次

WordPressの表示に4秒以上かかっていた

まず、体感ではなく実際にどの程度時間がかかっているか確認しました。PowerShellでWordPressトップページの取得時間を測定します。

PowerShell
Measure-Command {
    Invoke-WebRequest http://localhost/ -UseBasicParsing | Out-Null
}

3回測定した結果は次のとおりです。

回数TotalMilliseconds
1回目約4,473ms
2回目約4,471ms
3回目約4,556ms

毎回ほぼ4.5秒かかっています。管理画面でも同じように待たされるため、単純にブラウザの描画だけが遅い状態ではなさそうです。

OPcacheが有効か確認する

PHPの実行が遅い原因として、最初にOPcacheを確認しました。OPcacheはコンパイル済みのPHPコードをメモリへ保持し、PHPファイルを毎回コンパイルする処理を減らす仕組みです。

Dockerコンテナ内の設定は次のコマンドで確認できます。

コマンド
docker exec wp php -i | Select-String "opcache.enable"

確認結果は次のとおりでした。

実行結果
opcache.enable => On => On
opcache.enable_cli => Off => Off
opcache.enable_file_override => Off => Off

opcache.enableOnです。opcache.enable_cliOffですが、これはCLIでPHPを実行した場合の設定です。Apache経由で表示するWordPressではOPcacheが有効になっています。

今回の遅さはOPcacheが無効になっていることが原因ではありませんでした。

PHPそのものが遅いのか確認する

次にWordPressを通さずPHPだけを実行した場合の応答時間を確認しました。/var/www/html/test.phpに次の単純なPHPファイルを作成します。

test.php
<?php echo "OK";

PowerShellからアクセス時間を測定します。

コマンド
Measure-Command {
    Invoke-WebRequest http://localhost/test.php -UseBasicParsing | Out-Null
}

結果は次のとおりです。

回数TotalMilliseconds
1回目約23ms
2回目約43ms
3回目約14ms

WordPressでは約4.5秒かかっていましたが、単純なPHPファイルなら数十msで応答しています。この結果からApacheやPHP自体が4秒以上かかっているわけではなさそうです。

というワケで、確認が終わったので検証用のtest.phpは削除します。

コマンド
docker exec wp rm /var/www/html/test.php

WordPress.orgへの外部通信も確認する

WordPressやプラグインは更新確認などで外部サーバーへ通信する場合があります。外部通信やDNS名前解決で待たされている可能性も考え、WordPress.orgへの通信を確認しました。

まず、名前解決を確認します。

コマンド
docker exec wp php -r "var_dump(gethostbyname('api.wordpress.org'));"
実行結果
string(11) "66.6.42.251"

IPアドレスが返ってきたため、DNS名前解決はできています。続いて、WordPress.orgへのHTTPS通信にかかる時間を測定しました。

コマンド
Measure-Command {
    docker exec wp php -r "file_get_contents('https://api.wordpress.org/core/version-check/1.7/');"
}
実行結果
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 710
Ticks             : 7106966
TotalDays         : 8.22565509259259E-06
TotalHours        : 0.000197415722222222
TotalMinutes      : 0.0118449433333333
TotalSeconds      : 0.7106966
TotalMilliseconds : 710.6966

3回とも約0.7秒でした。多少時間はかかっていますが、WordPressを表示するたびに約4.5秒待たされる状態を説明できるほどではありません。

ここまでの確認でPHPそのものやOPcache、DNSが主な原因とは考えにくい状態でした。

Windows側のWordPressをbind mountしていた

次に確認したのがDocker Composeのvolume設定です。元の環境ではWindows側にWordPress一式を配置していました。

D:\wordpress
└─ wordpress_files

Docker Composeではこのディレクトリ全体を/var/www/htmlへbind mountしています。

docker-compose.yaml
  wordpress:
    #(中略)
    volumes:
      - ./wordpress_files:/var/www/html

この構成にはWindowsからWordPress本体やテーマ、プラグインを直接編集できる利点があります。ですが、WordPressは1ページを表示するだけでも多数のPHPファイルを読み込みます。

先ほど確認したtest.phpは単一のファイルなので高速でしたが、WordPressではコア、テーマ、プラグインなど多くのファイルへアクセスします。

Windows側のファイルシステムとLinuxコンテナの間で大量のファイルアクセスが発生していることが、遅さに影響している可能性があります。

WordPressをnamed volumeへ置くと約100msまで高速化した

ということで、bind mountの影響を確認するためWordPress本体をDockerのnamed volumeへ置いたテスト環境を作成しました。

docker-compose.yamlでWordPress側のvolumeを次のようにします。

docker-compose.yaml
  wordpress:
    #(中略)
    volumes:
      - wordpress_data:/var/www/html

ファイルの末尾にもvolumeを定義します。

docker-compose.yaml
# (中略)
volumes:
  db_data:
  # 下記を追加
  wordpress_data:

この構成では、WordPressのファイルをWindows側ではなくDockerが管理するvolumeへ保存します。

同じようにトップページの応答時間を3回測定しました。

回数TotalMilliseconds
1回目約141ms
2回目約67ms
3回目約142ms

Windows側へWordPress全体をbind mountしていた環境と比べると、大きな差があります。

構成応答時間
Windows側のWordPress一式をbind mount約4.5秒
WordPress本体をnamed volumeへ保存約0.1秒

この結果からWordPress全体をWindows側へ置いていた構成が大きなボトルネックになっていることが分かりました。

Windows側のWordPress一式をbind mountした変更前と、named volumeへ置いた変更後の構成比較

既存のWordPressをnamed volumeへ移行する

テスト用WordPressでは効果を確認できましたが、実際に使っているローカル環境を一から作り直す必要はありません。既存のWordPressファイルをnamed volumeへコピーすれば、現在の環境を引き継げます。

作業前にwordpress_filesのバックアップを残しておきます。

データベースは既存のdb_dataをそのまま利用するため、volumeを削除するdocker compose down -vは実行しません。

wordpress_dataを追加する

Composeファイルのvolume定義へwordpress_dataを追加します。

docker-compose.yaml
# (中略)
volumes:
  db_data:
  # 下記を追加
  wordpress_data:

続いて、Composeのリソースを作成します。

コマンド
docker compose create

作成されたvolumeは次のコマンドで確認できます。

コマンド
docker volume ls

今回の環境では次のvolumeが作成されました。

実行結果
wordpress_wordpress_data

Windows側のWordPressをvolumeへコピーする

Windows側のD:\wordpress\wordpress_filesをnamed volumeへコピーします。

コマンド
docker run --rm `
  -v wordpress_wordpress_data:/dest `
  -v D:\wordpress\wordpress_files:/src `
  alpine sh -c "cp -a /src/. /dest/"

wordpress_wordpress_dataの部分はdocker volume lsで確認した実際のvolume名に合わせます。

コピー後は、次のコマンドで内容を確認できます。

コマンド
docker run --rm `
  -v wordpress_wordpress_data:/data `
  alpine ls -la /data

wp-adminwp-contentwp-includeswp-config.phpなどが表示されればWordPress一式がコピーされています。

WordPress本体のmount先を変更する

WordPressサービスのvolume設定を変更します。変更前はWordPress全体をWindows側からbind mountしていました。

docker-compose.yaml
# (中略)
  wordpress:
    #(中略)
    volumes:
      - ./wordpress_files:/var/www/html

変更後は/var/www/htmlにnamed volumeを使用します。

docker-compose.yaml
# (中略)
  wordpress:
    #(中略)
    volumes:
      - wordpress_data:/var/www/html

設定後にコンテナを起動します。

コマンド
docker compose up -d

既存環境でも再度トップページの応答時間を測定しました。

回数TotalMilliseconds
1回目約123ms
2回目約99ms
3回目約89ms

テスト環境だけでなく、既存WordPressでも約100msまで短縮できました。

named volumeへの移行後に外部ファイルの読み込みがタイムアウトした

WordPress本体をnamed volumeへ移したところ、HTMLの応答は速くなりました。一方、ブラウザではCSSやJavaScript、画像などの外部ファイルを読み込めず、画面が正しく表示されない現象が発生しました。

Chromeのデベロッパーツールで確認すると、複数の外部ファイルが読み込みに失敗していました。個別のリクエストではWebサーバーとの接続確立に約30秒かかり、そのままタイムアウトしています。

Chrome DevToolsのNetworkタブでCSSなどの読み込み失敗とInitial connection 30.01秒を確認した画面

ファイルが存在しない場合に返される404エラーではなく接続確立に時間がかかったまま失敗しているため、named volume内にファイルがないことが直接の原因とは判断できません。テーマだけでなくWordPress本体やプラグインのファイルも失敗しており、特定のテーマディレクトリだけで発生している問題ではなさそうです。

この画面だけではWebサーバー、コンテナとの接続経路など、どの段階に原因があるかまでは特定できませんでした。ひとまず、themespluginsをWindows側からbind mountすると外部ファイルを再び読み込めるようになりました。ただ、この変更で解消した理由はヨクワカリマセンデシタ。

必要なファイルをWindows側へbind mountする

テーマファイル・プラグインファイル

外部ファイルとして参照する可能性のあるthemespluginsのディレクトリ全体をWindowsにマウントします。テーマ(子テーマがある場合は子テーマ)のfunctions.phpなどもWindows側で編集する可能性があるので、外部参照はされませんがWindows側にあったほうが便利です。

docker-compose.yaml
  wordpress:
    #(中略)
    volumes:
      # テーマとプラグインのディレクトリを追加
      - ./wordpress_files/wp-content/plugins:/var/www/html/wp-content/plugins
      - ./wordpress_files/wp-content/themes:/var/www/html/wp-content/themes

編集する可能性のあるファイル

上記のファイルの他にwp-config.phpなど編集する可能性のあるファイルもWindows側に配置してWindowsで編集できるようにしたほうがスムーズに運用できますよね。同じディレクトリにほかにほしいファイルがいまのところなかったので、wp-config.phpはファイル単位で指定してあげることにしました。

docker-compose.yaml
  wordpress:
    #(中略)
    volumes:
      # wp-config.phpをファイル単体で追加
      - ./wordpress_files/wp-config.php:/var/www/html/wp-config.php
wp-config.php、plugins、themesをWindows側からbind mountし、ほかのWordPressファイルをnamed volumeへ置く最終構成

Composeファイルの今回変更分をまとめると下記のようになりました。

docker-compose.yaml
  wordpress:
    #(中略)
    volumes:
      - wordpress_data:/var/www/html
      - ./wordpress_files/wp-content/plugins:/var/www/html/wp-content/plugins
      - ./wordpress_files/wp-content/themes:/var/www/html/wp-content/themes
      - ./wordpress_files/wp-config.php:/var/www/html/wp-config.php

volumes:
  db_data:
  wordpress_data:

bind mountを追加するとnamed volume内の同じパスにある内容はマウント中に隠れ、Windows側のファイルが使われます。

コンテナを起動する前にwordpress_files/wp-content/pluginswordpress_files/wp-content/themeswordpress_files/wp-config.php必要なファイルが存在することを確認してください

最終構成で応答時間を再確認する

テーマ、プラグイン、wp-config.phpをWindows側からbind mountした状態でも、トップページの応答時間を3回測定します。

コマンド
Measure-Command {
  Invoke-WebRequest http://localhost/ -UseBasicParsing | Out-Null
}
回数TotalMilliseconds
1回目約1,309ms
2回目約1,422ms
3回目約1,522ms

WordPress一式をnamed volumeへ置いた構成より応答時間は長くなりましたが、外部ファイルを読み込める状態で約1.3~1.5秒でした。WordPress全体をWindows側からbind mountしていた約4.5秒と比べると、応答時間は短縮されていますね。

DockerのWordPressが遅いときはmount先を見直す

Dockerで動かすWordPressが遅い場合はPHPやOPcacheだけでなく/var/www/html のmount元も確認してみてください。今回の環境ではWordPress一式をWindows側からbind mountしていた構成がボトルネックとなっていました。WordPress本体をnamed volumeへ移すことでHTMLの応答時間を約4.5秒から約1.5秒まで短縮できています。

ですが、すべてのファイルをnamed volumeへ置くとWindows側から編集しにくくなります。今回はWordPress本体の大部分をnamed volumeへ置きthemespluginswp-config.phpだけをWindows側からbind mountしました。テーマのCSSやJavaScriptなどをWebサーバーから配信しつつ、テーマやプラグイン、設定ファイルはWindows側で編集できる構成です。

ローカルWordPressだけが極端に遅い場合は単純なPHPファイルとWordPressの応答時間を比較したうえでDocker Composeのvolumes設定を確認すると原因を絞り込みやすくなります。WordPress全体をbind mountするのではなく]Windows側で扱う必要があるファイルだけを切り分けるのがポイントです


ローカル環境の改善後にWordPress本体の更新・セキュリティ・プラグイン開発も確認したい場合は、WordPressまとめから目的別に探せます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次