閉じる

技術ブログ

WP-CLIでドメインをテスト環境から本番環境に変更する方法 ── search-replace 徹底解説

2026.03.04
WP

WP-CLI 実践シリーズ #03
WP-CLIでドメインを
テスト環境から本番環境に変更する
search-replace は「ただの置換」ではない。
シリアライズデータを安全に書き換える、唯一の正解。

WordPressをテスト環境(ローカルやステージング)から本番環境に移行するとき、ドメイン(URL)の変更は避けて通れません。
データベースのあちこちに埋め込まれたURLを、正確に、安全に、一括で書き換える。
その答えが wp search-replace コマンドです。

この記事では、なぜこのコマンドが必要なのかから、実際の手順やってはいけない落とし穴まで、Seeds Brainsの総力を挙げて徹底解説します。


1. なぜ「ドメイン変更」が必要になるのか

WordPressは、サイトのURLをデータベースの中に保存しています。テーマやプラグインの設定、メディアのパス、内部リンク、ウィジェットの内容──あらゆる場所にURLが埋め込まれています。

1-1. URLが格納されている場所

テーブル カラム 格納されている内容
wp_options option_value siteurl, home, ウィジェット設定, プラグイン設定
wp_posts post_content 記事本文中の画像パス, 内部リンク
wp_posts guid 投稿の一意識別子(RSS用)
wp_postmeta meta_value ACFフィールド値, アイキャッチ画像パス
wp_comments comment_content コメント内のURL
wp_termmeta meta_value カテゴリ・タグのメタ情報

テスト環境のURLのままだと何が起きるか?

画像が表示されない
src="http://localhost:8088/wp-content/uploads/..."
本番では localhost に接続できない
リダイレクトループ
siteurlがテスト環境のまま → ブラウザとWordPressの認識が食い違い無限ループ
管理画面に入れない
ログイン後、テスト環境のURLにリダイレクトされてしまう

1-2. テスト環境→本番でURLが変わる典型パターン

環境 URL例 用途
ローカル(XAMPP) http://localhost/mysite/ 開発・デバッグ
ローカル(Docker) http://localhost:8088/ Docker環境での開発
ステージング https://stg.example.com/ お客様確認用
本番 https://www.example.com/ 公開サイト

2. なぜ sed や SQL の REPLACE ではダメなのか

「URLの置換なら sed や SQL の REPLACE() でいいのでは?」──これは最も危険な思い込みです。

2-1. シリアライズデータの罠

WordPressはプラグインやウィジェットの設定値をPHPのシリアライズ形式でデータベースに保存しています。

# PHPのシリアライズ形式の例
a:2:{s:4:”home”;s:24:”http://localhost:8088/wp”;s:7:”sidebar”;s:15:”default-sidebar”;}

# ↑ 注目: s:24 は「次の文字列が24文字」という意味
# “http://localhost:8088/wp” ← 確かに24文字

ここで sed や SQL の REPLACE() を使って localhost:8088www.example.com に置換すると……

sed / REPLACE() で置換した結果
a:2:{s:24:”http://www.example.com/wp”;s:7:”sidebar”;s:15:”default-sidebar”;}

# s:24 のままだが、
# “http://www.example.com/wp” は 25文字!
# → 文字数が合わない → PHPがデシリアライズに失敗
# → データが壊れる → 設定値が消える

結果:ウィジェット消滅、プラグイン設定初期化

wp search-replace で置換した結果
a:2:{s:25:”http://www.example.com/wp”;s:7:”sidebar”;s:15:”default-sidebar”;}

# s:25 に自動修正!
# “http://www.example.com/wp” は 25文字 → 正しい
# → PHPが正常にデシリアライズできる
# → データは完全に保持される

結果:すべての設定が安全に移行される

絶対にやってはいけない:
sed -i 's/localhost:8088/www.example.com/g' dump.sql
UPDATE wp_options SET option_value = REPLACE(option_value, 'localhost', 'www.example.com');

これらのコマンドはシリアライズデータの文字数カウントを破壊します。
実行した瞬間、ウィジェット、ACFフィールド、プラグイン設定が壊れます。
復旧にはバックアップからの復元しかありません。

2-2. wp search-replace が賢い理由

wp search-replace は単なるテキスト置換ではありません。内部で以下の処理を行っています:

wp search-replace の内部動作
1 値を読み取る
データベースの各カラムから値を1件ずつ読み取る
2 シリアライズを検出
値がシリアライズされたデータかどうかを判定。シリアライズなら一旦PHPオブジェクトにデシリアライズ
3 再帰的に置換
デシリアライズされたオブジェクトの中を再帰的にたどり、文字列を置換
4 再シリアライズ
置換後のオブジェクトを正しい文字数カウントで再シリアライズしてDBに書き戻す

この「デシリアライズ → 置換 → 再シリアライズ」の3ステップがあるからこそ、シリアライズデータ内のURLも安全に書き換えられるのです。


3. wp search-replace の基本

3-1. 基本構文

wp search-replace ‘置換前の文字列’ ‘置換後の文字列’ [テーブル…] [オプション]

3-2. 最もシンプルな使い方

# テスト環境 → 本番環境のドメイン変更
wp search-replace ‘http://localhost:8088’ ‘https://www.example.com’

+——————+———————–+————–+——+
| Table | Column | Replacements | Type |
+——————+———————–+————–+——+
| wp_options | option_value | 12 | PHP |
| wp_posts | post_content | 48 | SQL |
| wp_posts | guid | 35 | SQL |
| wp_postmeta | meta_value | 8 | PHP |
+——————+———————–+————–+——+
Success: Made 103 replacements.

出力の見方:
Type: PHP = シリアライズデータ内の置換(文字数カウントも修正済み)
Type: SQL = 通常のテキスト置換

PHPタイプの置換が含まれている場合、wp search-replace を使う価値が特に高いです。

3-3. 必ず –dry-run で確認してから実行

いきなり本番データを書き換えるのは危険です。まず --dry-run何が変わるかを確認しましょう。

# 実際には置換せず、件数だけ確認する
wp search-replace ‘http://localhost:8088’ ‘https://www.example.com’ –dry-run

+——————+———————–+————–+——+
| Table | Column | Replacements | Type |
+——————+———————–+————–+——+
| wp_options | option_value | 12 | PHP |
| wp_posts | post_content | 48 | SQL |
| wp_posts | guid | 35 | SQL |
| wp_postmeta | meta_value | 8 | PHP |
+——————+———————–+————–+——+
Success: 103 replacements to be made.

# ↑ “to be made” = まだ実行していない

鉄則: 本番環境では 必ず --dry-run で確認してから実行してください。
置換件数が想定と大きく異なる場合は、置換文字列が間違っている可能性があります。

4. 実践:テスト環境→本番環境の完全手順

ここからは、実際にテスト環境から本番環境にWordPressを移行する手順を、ステップバイステップで解説します。

移行の全体フロー
STEP 1
バックアップ
STEP 2
DB移行
STEP 3
search-replace
STEP 4
動作確認

STEP 1:バックアップを取る

移行作業の前に、テスト環境と本番環境の両方でバックアップを取ります。

# テスト環境でDBバックアップ
wp db export backup_test_$(date +%Y%m%d_%H%M%S).sql

→ Success: Exported to ‘backup_test_20260318_130000.sql’.

# 本番環境でもDBバックアップ(万が一の復旧用)
wp db export backup_prod_$(date +%Y%m%d_%H%M%S).sql

前回の記事WP-CLIでファイルやデータベースのバックアップ」で詳しく解説しています。まだ読んでいない方は先にご覧ください。

STEP 2:データベースを本番環境に移す

# テスト環境からエクスポートしたSQLを本番環境にインポート
wp db import backup_test_20260318_130000.sql

→ Success: Imported from ‘backup_test_20260318_130000.sql’.

STEP 3:wp search-replace でドメインを一括変更

ここが本記事の核心です。

# まず –dry-run で確認
wp search-replace ‘http://localhost:8088’ ‘https://www.example.com’ –dry-run

# 問題なければ本番実行
wp search-replace ‘http://localhost:8088’ ‘https://www.example.com’

+——————+———————–+————–+——+
| Table | Column | Replacements | Type |
+——————+———————–+————–+——+
| wp_options | option_value | 12 | PHP |
| wp_posts | post_content | 48 | SQL |
| wp_posts | guid | 35 | SQL |
| wp_postmeta | meta_value | 8 | PHP |
| wp_comments | comment_content | 0 | SQL |
+——————+———————–+————–+——+
Success: Made 103 replacements.

http → https の変更も同時に行う場合:
テスト環境が http:// で本番が https:// の場合、プロトコルの変更も含めて一度に置換できます。
別々に実行する必要はありません。

STEP 3.5:パスの変更が必要な場合

サーバーのファイルパスが異なる場合は、パスの置換も必要です。

# ファイルパスも変更する場合
wp search-replace ‘/var/www/html’ ‘/home/username/public_html’

# Xserver の場合の典型的なパス変更
wp search-replace ‘/var/www/html’ ‘/home/sv6022/example.com/public_html’

STEP 4:動作確認

# サイトURLが正しく変わったか確認
wp option get siteurl
https://www.example.com

wp option get home
https://www.example.com

# キャッシュをクリア
wp cache flush
→ Success: The cache was flushed.

# パーマリンク構造を再生成
wp rewrite flush
→ Success: Rewrite rules flushed.

確認すべきポイント:

  • トップページが正しく表示されるか
  • 画像が表示されているか(特にメディアライブラリの画像)
  • 管理画面にログインできるか
  • 内部リンクが正しいURLになっているか
  • ウィジェットの設定が維持されているか

5. 応用テクニック

5-1. 特定のテーブルだけ置換する

# wp_options と wp_posts だけ置換
wp search-replace ‘http://localhost:8088’ ‘https://www.example.com’ wp_options wp_posts

# wp_posts のみ(記事内のURLだけ直したい場合)
wp search-replace ‘http://localhost:8088’ ‘https://www.example.com’ wp_posts

5-2. guid を除外する(推奨)

guid カラムはRSSフィードの一意識別子です。WordPress公式は「guidは変更すべきでない」としています。

# guid カラムを置換対象から除外
wp search-replace ‘http://localhost:8088’ ‘https://www.example.com’ –skip-columns=guid
guidとは?
guid (Globally Unique Identifier) はRSSリーダーが記事を識別するためのIDです。
変更すると、RSSリーダーが同じ記事を「新しい記事」として再表示してしまう可能性があります。
ただし、テスト環境のguidが本番で問題になることは稀なので、初回移行時は置換しても実用上は問題ありません。

5-3. マルチサイトでの置換

# マルチサイトの全サイトで置換
wp search-replace ‘http://localhost:8088’ ‘https://www.example.com’ –network

# 特定のサイトだけ置換
wp search-replace ‘http://localhost:8088’ ‘https://www.example.com’ –url=http://localhost:8088/site2/

5-4. 置換内容を詳しく見る

# どの行がどう変わるか、1件ずつ表示
wp search-replace ‘http://localhost:8088’ ‘https://www.example.com’ –dry-run –log

# CSVで出力(レビュー用)
wp search-replace ‘http://localhost:8088’ ‘https://www.example.com’ –dry-run –format=csv

5-5. 正規表現で柔軟に置換

# 正規表現を使う場合は –regex オプション
wp search-replace ‘http://(localhost|staging\.example\.com)’ ‘https://www.example.com’ –regex
注意: --regex を使う場合、シリアライズデータ内の置換は安全ではない可能性があります。
正規表現の結果、置換後の文字列長が変わる場合は文字数カウントの問題が発生し得ます。
可能であれば、正規表現ではなく固定文字列での置換を推奨します。

6. Docker 環境での活用

Docker で開発している場合、ローカルと本番のURL切り替えは日常的に発生します。

6-1. Docker → 本番サーバーへの移行

# Docker環境内でDBをエクスポート
docker exec -it wordpress-container wp db export /tmp/export.sql –allow-root

# ホストにコピー
docker cp wordpress-container:/tmp/export.sql ./export.sql

# 本番サーバーにアップロード後、インポート&置換
wp db import export.sql
wp search-replace ‘http://localhost:8088’ ‘https://www.example.com’

6-2. 本番DB → Docker環境に取り込む

本番のデータをローカルで検証したい場合は、逆方向の置換を行います。

# 本番サーバーでDBエクスポート
wp db export prod_dump.sql

# ローカルにダウンロード後、Dockerコンテナ内でインポート
docker exec -it wordpress-container wp db import /tmp/prod_dump.sql –allow-root

# 本番URL → ローカルURL に逆方向置換
docker exec -it wordpress-container wp search-replace ‘https://www.example.com’ ‘http://localhost:8088’ –allow-root

6-3. docker-compose.yml にWP-CLIを含める

# docker-compose.yml の例
services:
wpcli:
image: wordpress:cli
volumes:
./web/wp:/var/www/html
depends_on:
db
entrypoint: wp
command: “–info”

# 使い方
docker compose run –rm wpcli search-replace ‘旧URL’ ‘新URL’


7. トラブルシューティング

7-1. 「Error: YOAST SEO」等のプラグインエラーが出る

# プラグインを無効化してから実行
wp search-replace ‘旧URL’ ‘新URL’ –skip-plugins

# 特定のプラグインだけスキップ
wp search-replace ‘旧URL’ ‘新URL’ –skip-plugins=wordpress-seo

7-2. 置換したのに管理画面に入れない

キャッシュやブラウザのCookieが原因の場合があります。

# OPcacheをクリア
wp eval ‘opcache_reset();’

# transientキャッシュをクリア
wp transient delete –all

# .htaccess を再生成
wp rewrite flush –hard

それでもダメな場合は、wp-config.php に直接URLを指定:

// wp-config.php に追記(一時的な対処)
define(‘WP_HOME’, ‘https://www.example.com’);
define(‘WP_SITEURL’, ‘https://www.example.com’);

7-3. 置換漏れを探す

# 旧URLがまだ残っていないかチェック
wp db search ‘localhost:8088’

wp_options:option_value
1:a]
wp_postmeta:meta_value
42:http://localhost:8088/wp-content/uploads/2025/12/photo.jpg

# 見つかったら再度 search-replace
wp search-replace ‘localhost:8088’ ‘www.example.com’

7-4. メモリ不足エラー

# PHP のメモリ上限を増やして実行
wp search-replace ‘旧URL’ ‘新URL’ –skip-themes –skip-plugins

# php.ini の memory_limit を変更する方法も
php -d memory_limit=512M $(which wp) search-replace ‘旧URL’ ‘新URL’


8. チェックリスト:移行前後の確認事項

移行前

# 確認項目 コマンド
1 テスト環境のDBバックアップ wp db export
2 本番環境のDBバックアップ wp db export
3 ファイルのバックアップ tar -czf backup.tar.gz wp-content/
4 現在のURL確認 wp option get siteurl
5 dry-run で置換件数確認 wp search-replace '旧' '新' --dry-run

移行後

# 確認項目 コマンド / 確認方法
1 siteurl / home が正しいか wp option get siteurl && wp option get home
2 旧URLの残存チェック wp db search '旧ドメイン'
3 トップページ表示 ブラウザで確認
4 画像表示 記事内の画像が表示されるか
5 管理画面ログイン /wp-admin/ にアクセス
6 パーマリンク再構築 wp rewrite flush
7 キャッシュクリア wp cache flush
8 SSL(https)確認 Mixed Content警告がないか

まとめ

WordPressのドメイン変更は wp search-replace 一択です。

方法 安全性 シリアライズ対応 判定
wp search-replace 安全 対応 推奨
SQL の REPLACE() 危険 非対応 禁止
sed でSQLダンプ編集 危険 非対応 禁止
phpMyAdmin で手動変更 危険 非対応 禁止

手順はシンプルです:

  1. バックアップ: wp db export
  2. 確認: wp search-replace '旧URL' '新URL' --dry-run
  3. 実行: wp search-replace '旧URL' '新URL'
  4. 検証: wp option get siteurl、ブラウザで目視確認

たった4ステップで、数百箇所に散らばったURLを安全に一括変更できます。
シリアライズデータも壊さない。--dry-run で事前確認もできる。
これが WP-CLI の真骨頂です。

コマンド早見表
# ドメイン変更(基本)
wp search-replace ‘http://old-domain.com’ ‘https://new-domain.com’

# 事前確認(dry-run)
wp search-replace ‘http://old-domain.com’ ‘https://new-domain.com’ –dry-run

# guid除外(推奨)
wp search-replace ‘http://old-domain.com’ ‘https://new-domain.com’ –skip-columns=guid

# 旧URL残存チェック
wp db search ‘old-domain.com’

# URL確認
wp option get siteurl
wp option get home

# キャッシュ&パーマリンク再構築
wp cache flush
wp rewrite flush

作成: Seeds Brains(ジェイノーム業務支援AI)