本番運用中のWordPressをDocker Composeでローカル開発環境化すると、(1)ディレクトリ名のタイプミスによる403 Forbidden、(2)wp-config.phpがDB接続用の環境変数を無視する仕様によるDB接続エラー、(3)DB内のsiteurl/homeが本番ドメインのままになっていることによるリダイレクトループ、の3つの壁にほぼ確実にぶつかります。今回は実際に詰まった順番と、それぞれの直し方をまとめます。
背景
Xserverで運用しているWordPressのファイル一式をローカルにコピーし、docker-compose(wordpress + mysql + phpmyadmin)でローカル開発環境を作ろうとしました。一発で動くと思ってたんですが、docker compose up -dした後、立て続けに3つの問題にぶつかったんですよね。
罠1: 403 Forbidden(ディレクトリ名のタイプミス)
docker compose up -dは成功するのに、ブラウザでアクセスすると403 Forbiddenになりました。原因はdocker-compose.yml側で./public-html(ハイフン)と書いていたのに、実際のフォルダ名はpublic_html(アンダースコア)だったこと。
存在しないパスを指定すると、Dockerは空のディレクトリを新規作成してそのままマウントしてしまうため、「パスが間違っている」というエラーにはならず、「空のディレクトリが見えている」状態になります。これがけっこう紛らわしいポイントでした。
volumes:
- ./public_html:/var/www/html # ここのパスを実フォルダ名に合わせて修正
罠2: DB接続エラー(wp-config.phpが環境変数を無視する)
パスを直した後、今度はDBに繋がらないエラーになりました。公式のwordpressイメージは、DB_HOSTなどを環境変数で渡す使い方が一般的ですが、wp-config.phpがすでにDB接続情報を持っている場合、環境変数の方を無視する仕様になっています。
今回コピーしたwp-config.phpには本番(Xserver)のDB_NAME/USER/PASSWORD/HOSTがそのまま書かれていたので、docker-compose.yml側でいくら環境変数を設定しても反映されませんでした。
docker-compose.ymlだけ直す案も考えましたが、上記の仕様がある以上それでは解決しないと判断し、wp-config.php側も直接書き換える方針にしました。
define( 'DB_NAME', 'wordpress' );
define( 'DB_USER', 'wordpress' );
define( 'DB_PASSWORD', 'wordpress' );
define( 'DB_HOST', 'db:3306' ); // docker-composeのMySQLサービス名:ポート
本番のDB認証情報は、書き換えると同時にローカルのリポジトリからは完全に消える形にしました。本番の認証情報をローカル環境にも残さない、という方針です。
罠3: リダイレクトループ(DB内のsiteurl/homeが本番ドメインのまま)
ファイルとDB接続はこれで解決したのですが、まだブラウザで開けませんでした。アクセスするとhttp://localhost/(ポート番号無し)にリダイレクトされてしまい、ポートをマッピングしていないので繋がらない状態でした。
原因は、WordPressがDBのwp_optionsテーブルに保存しているsiteurl/homeの値が本番ドメイン(xsrv.jp)のままだったことです。ファイルをコピーしただけではこの値は変わらないので、ローカルのURL(http://localhost:8080など)に直接書き換える必要があります。
UPDATE wp_options SET option_value = 'http://localhost:8080' WHERE option_name IN ('siteurl', 'home');
これでようやく200 OKで表示されるようになって、ホッとしました。
番外: Chromeだけ繋がらない
ここまで直した後も、なぜかChromeだけ表示できず、VSCode内蔵ブラウザでは見られるという不思議な状態になりました。原因はブラウザ側に残っていた古いリダイレクト先のキャッシュで、Chromeのキャッシュをクリアしたら解消。ブラウザによって挙動が違う場合は、キャッシュの可能性も疑ってみてください。
まとめ
本番WordPressをDockerでローカル化するときに気をつけたいのは、問題が「ファイルパス」「wp-config.php」「DB内のオプション値」という複数のレイヤーに分かれていることです。1つ直してもまだ繋がらない場合、別のレイヤーに原因が残っている可能性が高いかなと。
- ディレクトリ名は実際のフォルダ名と完全に一致させる
wp-config.phpにDB接続情報が既にある場合、環境変数は無視されるので直接書き換える- DB内の
siteurl/homeもローカルのURLに更新する
よくある質問
docker-composeの環境変数でDB接続情報を渡しているのに反映されないのはなぜ?
wp-config.phpが既にDB接続情報を持っている場合、公式のwordpressイメージはそちらを優先し、環境変数を無視します。wp-config.php側を直接書き換える必要があります。
siteurl/homeはWP管理画面からも変更できますか?
ログインできる状態であれば「設定」→「一般」から変更できますが、リダイレクトループでログイン画面自体に到達できない場合は、phpMyAdminなどからDBを直接書き換える必要があります。
本番のDB認証情報はローカル環境にどう扱えばいいですか?
本番の値はローカルのリポジトリに残さず、ローカル用の分かりやすい値に書き換えてしまうのがおすすめです。本番への誤上書きのリスクも減らせます。


コメント