このサイトでは、Next.jsの静的ファイルとWordPressが同じドキュメントルートに同居していました。記事はMarkdown管理に移しましたが、WordPressは引き続き使いたかったので、サブドメインに分けて、さらに自分のIPアドレスからしか見られないようにしました。Xserverでの手順をまとめます。
方針
- WordPressは
cms.example.comに移す - ファイルは移動ではなくコピーで進め、切り替えるまで元のWordPressは動かしたままにする
- 検索エンジンにはインデックスさせない
- 閲覧は許可したIPアドレスからのみ
1. サブドメインの追加
サーバーパネルの「サブドメイン設定」で追加します。ドキュメントルートは2択でしたが、どちらもメインドメインの public_html の中に作られます。
public_html/cms.example.com/public_html/cms/
メインドメインのページ名(/cms/)とぶつからないよう、ドメイン名のフォルダにしました。無料独自SSLも有効にし、証明書が発行されるまで(1時間ほど)待ちます。
2. バックアップ
XserverにはWP-CLIが最初から入っているので、データベースはWP-CLIで書き出します。バックアップは public_html の外に置きます。
$ cd ~/example.com/public_html
$ wp db export ~/example.com/backup/db.sql
$ tar czf ~/example.com/backup/wp-files.tar.gz wp-admin wp-content wp-includes wp-*.php index.php .htaccess
3. ファイルをコピー
$ rsync -a wp-admin wp-content wp-includes wp-*.php index.php xmlrpc.php cms.example.com/
サブドメインのフォルダには、Xserverの初期ファイル(index.html)が入っています。index.php より優先されてしまうので削除しておきます。
4. URLの置き換え
まず --dry-run で、何がいくつ置き換わるかを確認しました。
$ wp search-replace "https://example.com/wp-content" "https://cms.example.com/wp-content" \
--skip-columns=guid --dry-run --report-changed-only
置き換える範囲は絞っています。
- 画像のURL(
/wp-content/...)だけを置き換える - 記事中のメインサイトへのリンクは、そのまま残す
- GUIDは変えない(
--skip-columns=guid)。WordPressの公式ドキュメントでも、GUIDは変更しないよう案内されています
問題なければ --dry-run を外して実行し、サイトのURLを変更します。あわせて「検索エンジンでの表示」も「インデックスしない」にしました。
$ wp option update siteurl https://cms.example.com
$ wp option update home https://cms.example.com
$ wp option update blog_public 0
データベースは1つなので、この時点で元の場所のWordPressも新しいURLを向きます。SSLの発行前にやると管理画面に入れなくなるので、証明書が発行されてから行いました。
5. .htaccessでIPアドレス制限
サブドメイン側の .htaccess の先頭に追加しました(Apache 2.4の書き方です)。
# 許可した IP からのみ表示する
SetEnvIf Request_URI "^/\.well-known/" allow_acme
<RequireAny>
Require ip 203.0.113.10 # 自分の IP
Require ip 198.51.100.20 # サーバー自身(WP-Cron など)
Require env allow_acme # SSL 証明書の自動更新用
</RequireAny>
# メインドメインのパス(example.com/cms.example.com/)からのアクセスは 404
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} !^cms\.example\.com$ [NC]
RewriteRule ^ - [R=404,L]
</IfModule>
気をつけた点は3つです。
- サーバー自身のIPも許可する:WP-Cronなどは、サーバーからWordPressにアクセスします。サーバーの送信元IPは、SSHで
curl https://ifconfig.meを実行すれば確認できます .well-knownは開けておく:無料SSLの自動更新で外部からアクセスされるため- メインドメインのパスからも見えてしまう:サブドメインのフォルダはメインドメインの
public_htmlの中にあるので、example.com/cms.example.com/でもアクセスできてしまいます。ホスト名で判定して404にしています
設定が効いているかは、いったん自分のIPを外した状態で403になることを確かめてから、本番の設定に戻しました。
また、メインドメイン側の .htaccess の設定(ErrorDocument やヘッダーの設定など)は、サブディレクトリにあるサブドメイン側にも継承されます。一方、mod_rewrite のルールは、子の .htaccess で RewriteEngine On を書くと親のルールは使われません。この違いに注意が必要です。
6. 元の場所の片付け
サブドメインで管理画面にログインでき、記事の編集もできることを確認してから、public_html 直下のWordPressのファイルを削除しました。メインドメインの .htaccess も、WordPress用のルールを外して静的サイト用に書き直しています。
まとめ
wp search-replaceは--dry-runで範囲を確認し、GUIDは変えない- IP制限は「サーバー自身」と「
.well-known」を忘れずに - 回線のIPアドレスが変わると管理画面に入れなくなるので、そのときはSSHやFTPで
.htaccessを書き換える