【保存版】WordPress移行の失敗学。別環境へ「確実に」復元するためのフルバックアップとWP-CLI活用術

「バックアップはあるのに、復元したらサイトが真っ白」なのはなぜ?

こんにちは!「LINUX工房」管理人の「リナックス先生」です。
普段はサーバーインフラの話を中心にしていますが、今回はWebアプリケーションの王様、WordPressのお話です。

サーバー移転や、本番環境からステージング環境へのコピー。
エンジニアなら日常茶飯事の作業ですが、こんな経験はありませんか?
「ファイルもDBも完璧にコピーしたはずなのに、トップページ以外が404エラーになる」
「画像が表示されない」
「管理画面にログインしようとすると、旧ドメインにリダイレクトされる」

コウ君

先生、助けてください!
クライアントのサイトを新しい高速サーバーに移転する案件なんですが、All-in-One WP Migration プラグインを使ったら「サイズ制限オーバー」で課金しろって言われました。
仕方ないからFTPで全部ダウンロードして、phpMyAdminでSQLをエクスポートして新サーバーに入れたんですけど……。
サイトは表示されるのに、リンクをクリックすると全部「旧サーバーのURL」に飛んじゃうんです!
SQLファイルをテキストエディタで一括置換したのに、なんで直らないんですか!?

リナックス先生

コウ君、それは「シリアライズ(直列化)データの罠」にハマったわね。
WordPressのデータベースには、文字数情報を含んだ特殊な形式でデータが格納されている箇所があるの。
それをテキストエディタで無理やり置換すると、文字数の整合性が取れなくなってデータが壊れるのよ。
プロはそんな時、WP-CLI というコマンドラインツールを使うの。
今日は、プラグインに頼らない「エンジニアのためのWordPress移行術」を徹底的に教えるわ。

本記事では、WordPressの構造理解から始まり、コマンドラインを使った高速バックアップ、データベースの整合性を保ったままドメインを書き換える「検索置換(Search-Replace)」のテクニックまで、プロの現場で使われているノウハウを余すことなく解説します。


第1章:敵を知る。WordPressのデータ構造とバックアップ対象

「WordPressのバックアップ」と言った時、具体的に何を指すのでしょうか?
「全部」では答えになっていません。
移行において必須となるのは、大きく分けて以下の2つです。

1. ファイル群(Document Root)

PHPプログラム本体や、アップロードされた画像ファイルです。
特に重要なのは以下のディレクトリとファイルです。

  • wp-content/: テーマ、プラグイン、アップロード画像が入っています。これさえあれば、他は公式サイトからダウンロードしたファイルでも代用可能です。
  • wp-config.php: データベースへの接続情報が書かれています。これがないとDBに接続できません。
  • .htaccess (または nginx.conf): パーマリンク設定(リライトルール)が書かれています。これがないとトップページ以外が404エラーになります。

2. データベース(MySQL / MariaDB)

記事の本文、設定情報、ユーザー情報、コメントなど、テキストデータはすべてここにあります。
WordPressは「ファイルがあってもDBがないと何も表示されない」システムです。

💡 プロの視点:プラグイン移行の限界
「All-in-One WP Migration」などのプラグインは優秀ですが、以下の弱点があります。
サイズ制限: 無料版は数百MBまで。
PHPタイムアウト: 巨大なサイトだと処理中にPHPの実行時間制限(max_execution_time)に引っかかり、途中で止まる。
ブラックボックス: エラーが出た時に、どこで止まったか原因究明が困難。
エンジニアなら、OSレベルのコマンドを使って、確実かつ高速に処理する方法をマスターすべきです。


第2章:【ファイル編】tarコマンドでパーミッションごと固める

FTPソフトで数万個のファイルをちまちまダウンロードするのはやめましょう。
時間がかかる上に、転送エラーのリスクがあります。
SSHでサーバーに入り、tar コマンドで一撃でアーカイブします。

バックアップコマンド

ドキュメントルートが /var/www/html だとします。

cd /var/www
# htmlディレクトリを丸ごと圧縮
# z: gzip圧縮, c: 作成, v: 詳細表示, f: ファイル出力, p: パーミッション保持
tar zcvfp wp-files-backup.tar.gz html/

ポイントは p オプションです。
これを付けることで、ファイルの所有者やパーミッション情報(755, 644など)を保持したままアーカイブできます。
展開した後に「書き込み権限がなくて画像がアップロードできない!」というトラブルを防げます。

除外すべきディレクトリ

キャッシュプラグインなどが生成した巨大なキャッシュファイルや、バックアッププラグインが作った過去のバックアップファイルは、移行には不要です。
--exclude オプションで除外しましょう。

tar zcvfp wp-files-backup.tar.gz html/ \
  --exclude='html/wp-content/cache/*' \
  --exclude='html/wp-content/backups/*' \
  --exclude='html/wp-content/uploads/2015/*' # 古い画像がいらない場合など

第3章:【DB編】mysqldumpのオプションと文字コードの罠

次はデータベースです。
phpMyAdminのエクスポート機能は、巨大なDBだとタイムアウトしたり、ブラウザが固まったりします。
ここもコマンドラインの mysqldump を使いましょう。

基本のダンプコマンド

wp-config.php に書かれているDB情報を元に実行します。

# -u: ユーザー, -p: パスワード入力, -h: ホスト
mysqldump -u wp_user -p -h localhost wp_database_name > wp-db-backup.sql

【重要】プロが使う必須オプション

本番環境でダンプを取る場合、サイトを停止させないために以下のオプションが必須です。

mysqldump -u wp_user -p wp_db \
  --single-transaction \
  --quick \
  --hex-blob \
  --default-character-set=utf8mb4 \
  > wp-db-backup.sql
  • --single-transaction: InnoDBテーブルの場合、テーブルをロックせずに整合性のあるバックアップを取ります(サイトが止まりません)。
  • --quick: データをメモリに展開せず、一行ずつ処理します。巨大なDBでもメモリ不足になりません。
  • --hex-blob: バイナリデータ(画像データなどがDBに入っている場合)を16進数文字列としてダンプします。文字化け防止になります。
  • --default-character-set=utf8mb4: 絵文字などを含む現代のWordPressでは必須です。ここを間違えると文字化けします。

💡 転送のテクニック
作成した .tar.gz.sql ファイルは、scprsync で新サーバーへ直接転送しましょう。
一旦ローカルPCに落とすのは時間の無駄です。
scp wp-files-backup.tar.gz user@new-server:/home/user/


第4章:別環境への展開と wp-config.php の修正

新サーバー(またはローカル環境)にデータを配置します。

1. ファイルの展開

# 新サーバーにて
cd /var/www
tar zxvf wp-files-backup.tar.gz

2. データベースのインポート

まず、新サーバー側で空のデータベースとユーザーを作成しておきます。

# MySQLにログイン
mysql -u root -p

# DB作成
CREATE DATABASE new_wp_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
# ユーザー作成と権限付与
GRANT ALL PRIVILEGES ON new_wp_db.* TO 'new_user'@'localhost' IDENTIFIED BY 'new_password';
FLUSH PRIVILEGES;
EXIT;

作成したDBにデータを流し込みます。

mysql -u new_user -p new_wp_db < wp-db-backup.sql

3. wp-config.php の修正

旧サーバーと新サーバーでDB名やパスワードが違う場合、wp-config.php を書き換える必要があります。

/** WordPress のためのデータベース名 */
define( 'DB_NAME', 'new_wp_db' );

/** MySQL データベースのユーザー名 */
define( 'DB_USER', 'new_user' );

/** MySQL データベースのパスワード */
define( 'DB_PASSWORD', 'new_password' );

/** MySQL のホスト名 */
define( 'DB_HOST', 'localhost' );

これで「サイトが表示されるはず」ですが、ドメインが変わっている場合(例:example.comdev.example.com)、レイアウトが崩れたり、画像が表示されなかったりします。
ここからが本番です。


第5章:最大の難所。「シリアライズデータ」とWP-CLIによる置換

WordPressのデータベースには、サイトURL(siteurl, home)以外にも、記事本文やウィジェットの設定、テーマのオプションなどに絶対パス(http://old-domain.com/...)が大量に含まれています。

なぜSQLをテキスト置換してはいけないのか?

WordPressは、配列やオブジェクトをDBに保存する際、PHPの serialize() 関数を使います。
これは以下のような形式になります。

s:4:"test"; (文字列型、4文字、"test")

もし、この "test" を "testing"(7文字)にテキストエディタで置換するとどうなるでしょうか?

s:4:"testing";

文字数は7文字なのに、長さ定義は s:4 のままです。
PHPがこれを読み込もうとすると「データ破損」として扱われ、その設定項目ごと無視されます。
これが「移行したらウィジェットが消えた」「テーマ設定が初期化された」というトラブルの原因です。

救世主:WP-CLI (WordPress Command Line Interface)

これを解決するには、シリアライズデータを解釈して、文字数定義も正しく書き換えてくれるツールが必要です。
それが、WordPress公式のコマンドラインツール WP-CLI です。

WP-CLIのインストール

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp

search-replace コマンドによる安全な置換

ドキュメントルート(/var/www/html)に移動し、以下のコマンドを実行します。
※Webサーバーのユーザー(通常 www-datanginx)で実行するか、--allow-root オプションを付けます。

1. Dry Run(テスト実行)

# 旧ドメイン: old.com, 新ドメイン: new.com
wp search-replace 'http://old.com' 'https://new.com' --dry-run --allow-root

どのテーブルの何行が変更されるかが表示されます。

2. 本番実行

wp search-replace 'http://old.com' 'https://new.com' --allow-root

WP-CLIは、DB内のデータを一つずつPHPで復元し、中身を置換してから再度シリアライズして保存してくれます。
これにより、複雑なテーマオプションやプラグインデータも壊れることなく、完璧に新しいドメインへ移行されます。

💡 注意点:http と https
移行と同時にSSL化(http → https)する場合も、このコマンド一発で対応できます。
ただし、'old.com' ではなく 'http://old.com' のようにプロトコル込みで指定する方が安全です(メールアドレスのドメイン部分などを誤って置換しないため)。


第6章:仕上げ。パーミッション、Webサーバー設定、動作確認

データは整いましたが、最後に環境周りの整備が必要です。

1. ファイルの所有権(Owner)の修正

root ユーザーでファイルを展開すると、所有者が root になっていることがあります。
これではWebサーバーが画像アップロードやプラグイン更新を行えません。

# Nginx/Apacheの実行ユーザーに合わせる
chown -R www-data:www-data /var/www/html

2. パーマリンク設定の再保存

.htaccess が正しく反映されていない場合、下層ページが404エラーになります。
管理画面にログインし、「設定」→「パーマリンク設定」を開き、何も変更せずに「変更を保存」ボタンを押してください。
これにより、WordPressがリライトルールを自動的に再生成(フラッシュ)してくれます。

3. Nginxの場合の注意点

Apacheなら .htaccess が使えますが、Nginxの場合は nginx.conf (または default.conf) に以下の設定が必要です。

location / {
    try_files $uri $uri/ /index.php?$args;
}

これがないと、WordPressの「Pretty Permalinks(きれいなURL)」が動作しません。

4. キャッシュのクリア

移行元のサーバーでキャッシュプラグイン(WP Super Cache, W3 Total Cacheなど)を使っていた場合、wp-content/cache/wp-content/advanced-cache.php などの残骸が悪さをすることがあります。
表示がおかしい場合は、プラグインを一度無効化するか、キャッシュファイルを物理的に削除してみてください。


まとめ:移行スキルは、インフラエンジニアの基礎体力

お疲れ様でした!
今回は、WordPressの完全バックアップと、WP-CLIを使ったプロフェッショナルな復元手順について解説しました。

今回の重要ポイント:

  • ファイルは tar p で権限ごと固める。DBは mysqldump --single-transaction で止まずに抜く。
  • DBのテキスト置換はNG。シリアライズデータが壊れる。
  • wp search-replace を使えば、複雑なデータ構造も安全に置換できる。
  • 移行後はパーミッション修正とパーマリンクの再保存を忘れずに。
ウィンドウズ先生

今回はLinux環境の話でしたが、実はWindows Server (IIS) でWordPressを動かす場合も、考え方は全く同じです。
WP-CLIはWindowsでも動きますし、mysql.exe も使えます。
OSが何であれ、「アプリがデータをどう持っているか」を理解していれば、どんなトラブルも解決できるんですよ。

WordPressの移行案件は、フリーランスや副業でも非常に需要が高いスキルです。
「プラグインで失敗したから助けて!」というSOSに対応できるエンジニアは重宝されます。
ぜひ、自分の検証環境で一度、手動バックアップ&リストアを試してみてください。

Happy Migration!

▼ 移行の練習環境を作る ▼

WordPressを自由に壊して学ぶ
「おすすめVPS」

おすすめVPSを見る

Webインフラのプロへ
「ITエンジニア転職」

転職エージェントを見る

コメント