WordPress.com (Atomic) → Hostinger 移行手順メモ
ℹ️ この記事は Claude Code で書きました。
WordPress.com の Business/Commerce プラン (Atomic サイト、SFTP/SSH/phpMyAdmin が使える上位プラン) から Hostinger へ WordPress サイトを移行した際の手順と、実際にハマった点をまとめる。
前提
- 移行元が WordPress.com の Business 以上のプラン であること (SFTP/SSH/phpMyAdmin アクセスが無いプランでは今回の手順は使えない)
- Hostinger 側で SSH 接続が有効なプランであること
- ローカルに SSH 鍵ペアがあること (無ければ
ssh-keygenで作成)
全体の流れ
- WordPress.com 側から DB ダンプと
wp-content一式を取得 - Hostinger 側にまっさらな WordPress を新規作成
- DB をインポート、
wp-contentを展開 (文字化けの下ごしらえもここで) - 画像まわりの後処理 (サムネイル再生成、Photon CDN URL 修正)
- クリーンアップ (不要ファイル・不要 cron・デバッグモード等)
- 本番ドメインへの切り替え
- メール関連 DNS の罠
- ドメインの契約整理
- レジストラ移管 (WordPress.com → Hostinger)
1. WordPress.com 側からファイルを取得
WordPress.com 管理画面 →該当サイト→「ホスティング設定」 (Hosting Configuration) に SFTP/SSH 接続情報がある。
📶 SSH 接続
パスワード認証ではなく 公開鍵登録が必須 なケースがある。その場合はローカルの ~/.ssh/id_ed25519.pub の中身をコピーして、WordPress.com 側の SSH 鍵登録画面に貼り付ける。
登録後、以下の形式でログインできる (ユーザー名は SFTP/SSH 情報に表示されている <なにか>.wordpress.com@ssh.wp.com 形式)。
ssh <username>.wordpress.com@ssh.wp.com
Code language: Bash (bash)
🤐 wp-content 一式を tar でまとめる
WordPress.com 特有のドロップインファイル (advanced-cache.php, object-cache.php。実体はシンボリックリンクで、リンク先は WordPress.com 専用の Pressable/Atomic 基盤にしか存在しない) は移行先で動かないので、tar 化の時点で除外しておく。
cd htdocs # サイトルート(ls -la ~でシンボリックリンクの場所を確認)
tar czf ~/wp-content.tar.gz \
--exclude='wp-content/advanced-cache.php' \
--exclude='wp-content/object-cache.php' \
wp-content
Code language: Bash (bash)
⬇️ ダウンロード
WordPress.com の SSH 環境は scp のコマンド実行チャネルを許可しておらず、SFTP サブシステムのみ許可 していることがある。scp が Connection closed で失敗する場合は sftp を使う。
sftp <username>.wordpress.com@ssh.wp.com
sftp> get wp-content.tar.gz ~/Documents/
Code language: Bash (bash)
注意: sftp ログイン直後のカレントディレクトリは、ssh ログイン直後のホームディレクトリ (/home/<numeric-id>) とは異なることがある (/srv/htdocs など)。pwd で確認し、cd /home/<numeric-id> のように絶対パスで移動する。
🗃️ DB ダンプの取得
同じ「ホスティング設定」画面から phpMyAdmin を開き、エクスポート。
- エクスポート方法: 簡易
- フォーマット: SQL
- エンコーディングへの変換: なし (ここで EUC/SJIS に変換すると余計に文字化けするので触らない)
2. Hostinger 側の準備
hPanel で SSH を有効化 (初回は SSH 用パスワードの設定が必要)。
ssh -p <port> <hostinger-user>@<host>
Code language: Bash (bash)
hPanel の「WordPress をインストール」からまっさらな新規 WordPress を作成しておく。作成後、domains/<一時ドメイン>/public_html/ が実体。
DB 接続情報を確認:
cat wp-config.php | grep -E "DB_NAME|DB_USER|DB_PASSWORD|DB_HOST|table_prefix"
Code language: Bash (bash)
3. DB インポートと wp-content 展開
🗑️ 初期テーブルを削除
mysql -u <user> -p'<pass>' <dbname> -N -e "SHOW TABLES;" | while read t; do
mysql -u <user> -p'<pass>' <dbname> -e "DROP TABLE \`$t\`;"
done
Code language: Bash (bash)
🧑🍳 SQL ファイルの下ごしらえ
phpMyAdmin が吐き出すダンプには CREATE DATABASE/USE 文が含まれていて、インポート先の DB 名と食い違うと権限エラーになる。該当行を除去する。
grep -av "^CREATE DATABASE\|^USE \`<元の DB 番号>\`" dump.sql > dump_clean.sql
Code language: Bash (bash)
この時点でインポート前に文字化けの有無を確認・修正しておく (インポート後に直そうとすると余計にややこしくなるので必ず先に済ませる)。
wp option get blogname を後で実行したときに、日本語が 回れå³ã®å†…輪差 のような文字化けになる場合がある。これは WordPress.com 側の CHARSET=latin1 宣言と実データ (UTF-8) の食い違いを、phpMyAdmin のエクスポート処理が変換して壊してしまうために起きる。
原因の仕組みと Python での直し方は長くなるので別記事に切り出した: WordPress.com の DB エクスポートで日本語が文字化けする理由と直し方
要点だけ書くと:
CREATE TABLEのCHARSET=latin1をutf8mb4に書き換える (SET NAMES utf8mb4はそのまま)- ダンプファイル全体に対して「UTF-8 でデコード→ cp1252 (+フォールバック) でエンコードし直す」変換をかけて、実データのバイト列を修復する
- 修復後のファイル (
dump_fixed.sql等) をこの後のインポートで使う
🚚 インポート
mysql -u <user> -p'<pass>' <dbname> < dump_clean.sql # 文字化けが無ければこちら
mysql -u <user> -p'<pass>' <dbname> < dump_fixed.sql # 文字化け修正をした場合はこちら
Code language: Bash (bash)
✂️ wp-content 展開
rm -rf wp-content
tar xzf wp-content.tar.gz
rm wp-content.tar.gz
Code language: Bash (bash)
🧹 mu-plugins の掃除
WordPress.com 専用の wpcomsh (シンボリックリンクだが、リンク先が存在しないため壊れている) が残っていることがある。放置すると wp コマンド実行時に Warning が出る。
rm -f wp-content/mu-plugins/wpcomsh
rm -f wp-content/mu-plugins/wpcomsh-loader.php
Code language: Bash (bash)
4. 画像まわりの後処理
🌐 Photon (Jetpack CDN) の URL を実ドメインに戻す
WordPress.com は Jetpack の Photon 機能で、リサイズ画像をサーバー上に保存せず i0.wp.com/i1.wp.com/i2.wp.com 経由の動的 CDN として配信している。記事本文中の画像 URL がこの形式 (i0.wp.com/ドメイン/wp-content/uploads/...) になっていることがある。
wp search-replace 'i0.wp.com/<ドメイン>' '<ドメイン>' --all-tables --report-changed-only
wp search-replace 'i1.wp.com/<ドメイン>' '<ドメイン>' --all-tables --report-changed-only
wp search-replace 'i2.wp.com/<ドメイン>' '<ドメイン>' --all-tables --report-changed-only
Code language: Bash (bash)
🖌️ サムネイル再生成
Photon 経由で配信していた関係で、リサイズ済みの画像ファイル (-1024x576.png など) がサーバー上に実在しないことが多い。オリジナル画像しか無いので、WP-CLI で再生成する。
wp media regenerate --only-missing --yes
Code language: Bash (bash)
☝️ 大きな GIF/動画でメモリ不足になる場合
数十 MB 級の巨大アニメ GIF などを処理しようとすると、共有ホスティングのメモリ上限 (OS の cgroup 等によるハードリミット。php -d memory_limit= を上げても回避できない) でプロセスが Kill されることがある。
対策: 1 件ずつ別プロセスとして処理すれば、1 件失敗しても他が止まらない。
# 処理対象IDリストを作る(前回成功した分より後ろ、など条件を調整)
wp post list --post_type=attachment --order=DESC --orderby=ID --format=csv --fields=ID | tail -n +2 > ids.txt
# バックグラウンドで1件ずつ処理
nohup bash -c 'while read id; do wp media regenerate "$id" --only-missing --yes; done < ids.txt' > regen.log 2>&1 &
disown
Code language: Bash (bash)
進捗確認:
ps aux | grep "while read id" # プロセスが生きているか
tail -f regen.log # 進捗ログ
Code language: Bash (bash)
失敗した (処理できなかった) ID の特定:
grep -oP '(?<=\(ID )\d+(?=\))' regen.log | sort -n -u > success_ids.txt
sort -n ids.txt > ids_sorted.txt
comm -23 ids_sorted.txt success_ids.txt # 差分=未処理・失敗ID
Code language: Bash (bash)
失敗するのは大抵、数十 MB 級のアニメ GIF/動画/音声ファイル。オリジナルファイル自体は無事なので、記事の表示自体に大きな支障は無いことが多い (縮小版サムネイルが使われる一部箇所のみ影響)。
🔍 SVG のサイズ指定バグ
Inkscape 等で作成した SVG は width="200mm" のように 単位付き (mm) で寸法が書かれていることがある。SVG サポート系プラグインがこの単位を無視して「200」をそのままピクセル数として _wp_attachment_metadata に記録してしまい、画像が意図せず極端に小さく表示されることがある。
確認:
wp post meta get <attachment_id> _wp_attachment_metadata
grep -A10 "^<svg" <svgファイル> | grep -i "width\|height"
Code language: Bash (bash)
width="222.30376mm" のようになっていたら、96dpi 換算 (× 3.7795275591) でピクセル値に直してメタデータを更新する。
wp eval '
$meta = wp_get_attachment_metadata(<ID>);
$meta["width"] = (int) round(222.30376 * 3.7795275591);
$meta["height"] = (int) round(119.34114 * 3.7795275591);
wp_update_attachment_metadata(<ID>, $meta);
'
Code language: Bash (bash)
5. クリーンアップ
📚 不要な Jetpack 関連テーブル
wp db query "SHOW TABLES LIKE '%jetpack%'"
# 空なら削除してOK
wp db query "DROP TABLE wp_jetpack_sync_queue"
Code language: Bash (bash)
🪲 デバッグモード
問題切り分けのため一時的に有効化していた場合は元に戻す。
define( 'WP_DEBUG', false );
Code language: Bash (bash)
🔗 パーマリンク再保存
管理画面 設定→パーマリンク設定 で何も変えずに保存ボタンを押す (.htaccess のリライトルール再生成のため)。
⏰ 不要 cron イベントの削除
移行元でのみ使われていたプラグイン (Jetpack, VaultPress, AMP, WordPress.com Site Helper など) の cron イベントが、プラグイン本体の無い状態で残っていることがある。実害は無いが掃除しておく。
wp cron event list
wp cron event delete <hook 名>
Code language: Bash (bash)
🧂 認証キー・ソルトの再生成
wp config shuffle-salts
Code language: Bash (bash)
⚙️ 管理者アカウントの再確認
注意: Hostinger のインストールウィザードで新規に生成した管理者アカウントは、DB を丸ごとインポートすると 消えて、移行元の古い管理者アカウントに置き換わる。ウィザードで設定した新しいパスワードでログインしようとしても入れないので注意。
wp user list --role=administrator --fields=ID,user_login,user_email
# 移行元のアカウントが復活していたら、パスワードとメールを更新
wp user update <ID> --user_pass='<新しいパスワード>' --user_email='<正しいメールアドレス>'
Code language: Bash (bash)
📁 不要ファイルの削除
rm -rf wp-content/ai1wm-backups # 中身が空のスタブだけなら削除可
rm -f wp-content/mu-plugins/wpcomsh-loader.php
rm -f wp-content/debug.log
Code language: Bash (bash)
6. 本番ドメインへの切り替え
📝 hPanel でドメインを追加
Hostinger hPanel の「ドメイン」からサイトに本番ドメインを追加する。これだけで一時ドメインのサイトディレクトリ名がドメイン名に変わり (domains/<一時ドメイン>/ → domains/<本番ドメイン>/)、DB 接続情報 (DB_NAME/table_prefix) はそのまま引き継がれる。
wp-config.php の siteurl/home オプションも、ドメイン追加時点で自動的に本番ドメインへ更新されていることがある。
wp option get siteurl
wp option get home
Code language: Bash (bash)
📢 ネームサーバーの切り替え
ドメインを WordPress.com で購入している場合、DNS 管理も WordPress.com 側の「ドメイン管理」画面で行う。ネームサーバーを Hostinger のもの (hPanel のドメイン追加画面に表示される。例: athena.dns-parking.com, apollo.dns-parking.com) に変更する。
hPanel 側で「現在の DNS プロバイダーをそのまま使う」方式 (A/CNAME レコードだけ個別編集) と「ネームサーバーごと切り替える」方式の 2 択が提示されることがあるが、後々レジストラ移管もするなら ネームサーバーごと切り替える方式 で統一しておくと Hostinger 側の DNS ゾーンで一括管理できて楽。
✅ DNS 反映確認
ネームサーバーの反映は数分〜数時間かかる。反映途中は「NS レコードは新しいのに A レコードは旧環境の IP のまま」という状態になることがあるので、両方を別々に確認する。
dig +short NS <ドメイン> @8.8.8.8
dig +short <ドメイン> @8.8.8.8
Code language: Bash (bash)
WordPress.com (Automattic) 側の IP は 192.0.78.x 系で、レスポンスヘッダーに host-header: WordPress.com や x-ac: ..._atomic_bur が出る。Hostinger 側に切り替われば server: LiteSpeed, platform: hostinger が返ってくる。
--resolve オプションで DNS 反映を待たずに Hostinger 側の応答を先に確認することもできる。
curl -skI https://<ドメイン>/ --resolve <ドメイン>:443:<HostingerのIP>
Code language: Bash (bash)
👀 最終ドメインへの wp search-replace
hPanel のドメイン追加時点で siteurl/home や DB 内の URL がすでに置換済みになっていることもあるが、念のため確認・実行する。
wp search-replace '<一時ドメイン>' '<本番ドメイン>' --all-tables --report-changed-only
Code language: Bash (bash)
📜 SSL 証明書の発行確認
ドメイン追加直後は Let’s Encrypt 証明書の自動発行に時間がかかり、一時的に TLS ハンドシェイクが失敗する (SSL routines::tlsv1 alert internal error 等)。HTTP (平文) では先に応答が返ることがあるので、それで Hostinger 側が正しく動いているかだけ先に確認できる。
curl -sI http://<ドメイン>/ --resolve <ドメイン>:80:<HostingerのIP>
Code language: Bash (bash)
7. メール関連 DNS の罠
hPanel でドメインを追加すると、Hostinger 独自のメールサービス用 MX レコード (mx1.hostinger.com, mx2.hostinger.com) が 自動的に設定され、既存の MX (Google Workspace 等) を上書きしてしまう ことがある。
Google Workspace 等の外部メールサービスを使っている場合は、hPanel の DNS ゾーン編集画面で MX レコードを手動で正しい値に戻す必要がある (Google Workspace の場合は aspmx.l.google.com を含む 5 レコード)。
あわせて SPF レコード (TXT) が Hostinger のメールサービス用のみになっていないか確認し、必要なら外部サービスの include を追加する。
v=spf1 include:_spf.mail.hostinger.com include:_spf.google.com ~allCode language: plaintext (plaintext)
DMARC レコード (_dmarc の TXT) を誤って別の値で上書きしてしまわないよう、DNS ゾーンを編集する際は「名前」列 (レコードがどのサブドメイン向けか) を必ず確認する。
反映確認は dig で。
dig +short MX <ドメイン> @8.8.8.8
dig +short TXT <ドメイン> @8.8.8.8
dig +short TXT _dmarc.<ドメイン> @8.8.8.8
Code language: Bash (bash)
8. ドメインの契約整理
WordPress.com のアカウントには「サイトホスティングプラン」と「ドメイン登録 (レジストラ)」という 2 つの別々の契約が同居している。ホスティングプランを解約しても、ドメイン登録自体は影響を受けず、そのまま WordPress.com 上に残り続け、独立して更新料が発生し続ける。
ドメイン管理画面 (https://wordpress.com/domains/manage/all/overview/<ドメイン>) で以下を確認できる。
- 登録期限・自動更新の有無
- WHOIS プライバシー保護の状態 (オンなら実際の氏名・住所は公開されない。プロキシ業者の代理情報が表示される)
- ネームサーバーの設定状況
🧐 WHOIS で公開情報を確認する
whois <ドメイン> | grep -iE "registrant|admin|tech|organization|street|city|phone|email"
Code language: Bash (bash)
プライバシー保護がオンなら REDACTED FOR PRIVACY や代理業者名 (Knock Knock WHOIS Not There, LLC 等) が表示される。
9. レジストラ移管 (WordPress.com → Hostinger)
ドメイン自体の管理も Hostinger に一本化したい場合は、レジストラ移管を行う。
- WordPress.com のドメイン管理画面で「移管のロック」をオフにする
- 認証コード (EPP コード) を取得する。コードは WordPress.com アカウントのログインメールアドレス宛に届く (ドメインの WHOIS 用連絡先メールではない点に注意)
- Hostinger hPanel の「ドメインの移管」から、ドメイン名と認証コードを入力して申請
- 現レジストラ側からの確認メールを承認
- 完了まで通常 5〜7 日程度。この間 DNS 設定 (ネームサーバー) はそのまま維持されるので、サイト表示には影響しない
移管申請後、whois/RDAP でステータスが pendingTransfer になっていれば正常に進行中。
whois <ドメイン> | grep -iE "registrar:|domain status"
Code language: Bash (bash)
移管完了まではドメインの登録情報 (WHOIS プライバシー設定含む) は変更しない方が安全。完了後にあらためて設定を確認する。