さらに何にも頼れないときの最後のWordPressお引っ越し方法

先日、第11回 WP ZoomUP WordPressのバックアップやお引越しどうしてる?に参加させていただいたときに、堀江 圭介 さんという方が 『プラグインやサービスに頼れない場合における最後のお引っ越し方法』という発表をされていました。

プラグインを使った方法などに比べるとなかなかのローテクで、「がんばるな・・・」という感じでした。

手順はそれほど難しくないのですが、なぜかがんばっている感あふれる発表でした。
なぜか。
発表時間が短かったから・・・が最大の理由な気もしますが、それ以外にXSERVERのコンパネのファイルマネージャーを駆使したり、phpMyAdminを駆使してデータを書き換えているあたりでそのように感じてしまいました。

そこで私がもっとがんばるにはどうすれば良いかお伝えしましょう。
ちがいます。
さらに何にも頼れない中で引っ越しするにはどうすれば良いか。
phpMyAdmin が無い(あるいはダンプが大きすぎてアップロードできない)しファイルマネージャーも使えない。
また、発表ではそこまでたどり着かなかった、投稿の中などのURL変更も実施します。

もっとがんばる、とはいえこの手順は私が普段、頻繁に行っているものとほぼ同じ手順です。
私が普段とてもがんばっている、ということではなく、さほど難しいことではない、ということです。

前提

「何も無い」とはどういう状態なのか。
何も無いとそもそも WordPress が動きません。
移転元、移転先共に下記の制限があるものとします。

移転元/移転先の制限

  • Web サーバー、DB サーバー共に WordPress を動作させることが出来る状態で、データベース領域は準備されています
  • WordPress に追加のプラグインをインストールすることは許可されていません
  • URLを書き換えるにはどうしても必要だからとSearch Replace DBの安心安全を力説し、土下座してインストールする許可を得ています
  • Web ブラウザから使える上記以外のツール(ファイルマネージャー、phpMyAdmin など)はありません
  • 必要最低限の権限を持つユーザーで FTP、ssh 接続ができます
  • viエディタ、アーカイブなどの一般的な Unix コマンドを使うことが出来ます。
  • サーバーに上記で示した以外のコマンド、ツール、サービスなどをインストール・使用することは許可されていません
  • 用意されているクライアント端末にはFTP、ssh接続に必要なアプリケーションはインストールされています。
  • クライアント端末に、上記で示した以外のアプリケーションをインストールすることは許可されていません。

こんな環境、現実にあるでしょうか?
セキュリティ意識の高い大企業ならあるかもしれません。
貸与されたクライアント端末には、何やら長い管理番号が書かれたシールが貼られているかもしれません。
セキュリティルームみたいな、PCの持ち込み・持ち出しもさせてもらえない部屋に入れられ、スマホもちっちゃい金庫に入れさせられるかもしれません。
が、一般的なWeb制作会社でこのような環境での作業を求められることはあまり無いのかなと思います。

しかし、何かのトラブル、何かの行き違い、何かの障害によって作業環境が制約を受ける場合があるかもしれません。
そのような場合に、備えて無駄に「あんまり何にも頼れない」状況を知っておいてもいいかもしれません。
こじつけです。


※データベース領域は準備されていることとしたのは、データベース領域作成の権限なんかは付与してもらえないと考えたからです。
※セキュリティに厳しいのに ssh はいいのか。いいんだろうか。いいことにします。
※何かの抜け穴を見つけたかた、その抜け穴を使って作業してください。

その他の決まり事

あとでファイルやデータベースに対して操作したり修正する内容などは以下の通りです。
事前にこの情報が無いと作業ができないですよ、ということです。
実際の設定情報は、全くこの通りでは無いですので、ちゃんと情報をもらいましょう。
このままやったら全てエラーです。

移転元のデータベース情報は wp-config.php に書かれています。
移転元サイトの URL も普通は分かるんじゃないでしょうか。
移転先の情報については誰かに教えてもらう必要があります。

  • ホスト名(URL)

    移転元:https://src.example.com/

    移転先:https://dist.example.com/

  • Webのルートディレクトリ(ファイルの配置位置)

    移転元:/src/public_html

    移転先:/dist/public_html

  • FTP SSHユーザー・パスワード

    移転元 ユーザー名:src_user
    パスワード:src_pass
    移転先 ユーザー名:dist_user
    パスワード:dist_pass

    ※webサイトのホスト名(src.example.com、dist.example.com)とftpやssh先のホスト名が異なる場合があります。同じかどうかを確認しましょう。

  • 移転元のデータベース接続情報

    データベース名 src_database_name
    データベースのユーザー src_database_user_name
    データベースのパスワード src_database_user_password
    データベースのホスト名 src_database_host_name
    デフォルトキャラクターセット(文字セット) utf8mb4
  • 移転先のデータベース接続情報

    データベース名 dist_database_name
    データベースのユーザー dist_database_user_name
    データベースのパスワード dist_database_user_password
    データベースのホスト名 dist_database_host_name
    デフォルトキャラクターセット(文字セット) utf8mb4

大まかな手順

  1. :Web関連ファイルの圧縮
  2. :データベースダンプの取得・圧縮
  3. :圧縮した両ファイルを移行先にFTP転送
  4. :転送された圧縮済ファイルを解凍・配置
  5. :データベースダンプをデータベースにインポート
  6. :wp-config.phpのデータベース設定変更
  7. :データベース内のホスト名(など)を変更
  8. :アクセスしてみる

手順の最初に、Web関連ファイルを圧縮しています。
長く運用していると、画像ファイル数が膨大になりがちです。
画像ファイルは圧縮効率が悪いので、圧縮しても全体のサイズはあまり小さくなりません。

ではなぜ圧縮するのかというと、FTPではファイルごとにファイルをくれだのファイルのチェックだのが実行されるため、ファイル数が多い場合には単純にディレクトリごとFTPするととロスが非常に大きくなり、数倍~数十倍の時間がかることがあります
※ファイル数によります
もちろん、別途圧縮する時間は必要ですが、トータルでは短くなりますし、長いダウンロード時間の中で FTP 接続が途中で切れたりするリスクも回避することができます。

上記手順リストでの配色のセンスが悪すぎてかえって分かりにくい気もしますが、こうしてみるとデータベース関連の操作が結構あって、データベースがよくわからないとどうやって移転したらいいのか途方に暮れるというか、どの方法を選んだらいいのか分からなくなってしまうだろうなと思います。

そして、以下で説明していく手順の中で、コマンドラインで実行している箇所のみ記述してみます。

移転元

cd /src
tar cvzf public_html.tar.gz public_html
mysqldump --default-character-set=utf8mb4 -e -h src_database_host_name -u src_database_user_name -psrc_database_user_password src_database_name | gzip -c > src_database_name.dump.gz
lftp -u dist_user,dist_pass dist.example.com
lftp dist_user@dist.example.com:~> cd /dist
lftp dist_user@dist.example.com:/dist> put public_html.tar.gz
xxxxx bytes transferred
lftp dist_user@dist.example.com:/dist> put src_database_name.dump.gz
xxxxx bytes transferred
lftp dist_user@dist.example.com:/dist> bye
exit

移転先

cd /dist
tar xvzf public_html.tar.gz
gzip -d src_database_name.dump.gz
mysql --default-character-set=utf8mb4 -h dist_database_host_name -u dist_database_user_name -pdist_database_user_password < src_database_name.dump
vi public_html/wp-config.php

大まかにこのようなことをやるので、理解できる方や、「なーんだ」という方はこのページを読む必要はありません。

実施

1.移転元:Web関連ファイルの圧縮

sshで移行元に接続し、Web関連ファイルを全て圧縮します。

1-1.sshで移行元に接続

接続方法については前提として ssh 接続できるツールもインストールされているということで、省きましょう。
ssh クライアントはWindows では PuTTY、‎RLogin、後継版が開発されている Tera Term などが有名でしょうか。
また、Windows10 では標準でsshクライアントが搭載されるようになりました。
Mac は良く知らないのですが、ターミナルから ssh コマンドでやるんでしょうかね。

1-2.Web関連ファイルの圧縮

tar コマンドを使ってファイルを圧縮します。
/src/public_htmlがドキュメントルートなので、/srcに移動して、public_htmlを丸ごと圧縮しましょう。
(移動しなくてもできますが、移動した方がコマンドが楽です)

cd /src
tar cvzf public_html.tar.gz public_html

と打ち込んでいくと、現在のディレクトリに圧縮済みの public_html.tar.gz が出来ます。

以下説明

不要な方は飛ばしてください

1行目はディレクトリ移動とすぐ分かると思います。
2行目は何でしょうか。
文脈から圧縮してるのは分かりますが、これでどうなるというのか分からないかもしれません。
public_htmlを圧縮してpublic_html.tar.gzというファイルを作成しています。
tarはその圧縮のためのコマンドです。
cvzftarのオプションで
c : 新しいアーカイブを作成する
v : 処理したファイルの一覧を詳しく出力する
z : アーカイブをgzipにフィルターする(要するに、gzip圧縮する)
f : Fというアーカイブ・ファイルまたはデバイスを使う(作成するファイルを指定する)
という意味です。
UNIX サーバーだとzオプションが使えない場合もあるかもしれません。
その時はパイプして、いやもうパイプの説明はちょっとリンク先の wikipedia にゆずりますが、こう書きます。

tar cvf - public_html | gzip > public_html.tar.gz

2.移転元:データベースダンプの取得・圧縮

2-1.データベースのダンプ・圧縮

移転元のデータベース接続情報に従って、以下のように打ち込みます。

mysqldump --default-character-set=utf8mb4 -e -h src_database_host_name -u src_database_user_name -psrc_database_user_password src_database_name | gzip -c > src_database_name.dump.gz

と打ち込めば、現在のディレクトリにsrc_database_name.dump.gzという名前で、圧縮されたデータベースダンプが作成されます。

以下説明

不要な方は飛ばしてください

mysqldumpはその名前の通り、mysqlでダンプするためのコマンドです。
いや待て、ダンプって何だ、ダンプって。
直訳で「どさりと下ろす」という意味なので、まぁ、そういうことです。
データベースの中身をどさりと下ろすコマンドです。
それ以降、パイプ(縦線)まではtarコマンドのオプションです

–default-character-set : 文字セットを指定します。何も指定しないとutf8になるので、utf8mb4の場合は指定しましょう。それ以外の文字セットが使われていることはあまり無いと思います。
-e : 複数の VALUES リストを含む、複数行の INSERT 構文を使用します。これにより、ダンプファイルのサイズが小さくなり、ファイルがリロードされる際の挿入が高速化されます。
-h : データベースサーバーのホスト名
-u : データベースのユーザー名
-p : 後ろにスペースも無くパスワードが書かれていますが、合っています。パスワードです。スペースが無い歴史的理由はよく知りません。ここでパスワードを指定するのはセキュアでは無いと言われています。ここで書かなくても対話的に聞いてきますので、その時にパスワードを入力しても構いません。コマンドにこのオプションを指定することでセキュアでは無いとか何とかアラートが表示されることがあるかもしれませんが、無視できます。
これらオプションの後にデータベース名を指定します。

このmysqldumpコマンドは、ダンプした内容を標準出力にダラダラと出力するだけです。
ファイルを作ってくれたりはしません。
どさりと下ろすんで、あとはお好きにというコマンドです。
ですので、パイプ(縦線)を挟んでgzipコマンドに渡して圧縮ファイルにしてしまいます。
このgzipコマンドも圧縮した結果を標準出力に出すので、> src_database_name.dump.gz
と書いて、src_database_name.dump.gzというファイルに書き出しています。

3.圧縮した両ファイルを移行先にFTP転送

ここで、圧縮したファイルを移転先にFTP転送します。
もちろん、クライアント端末にFTPクライアントが入っていますので、一旦クライアント端末にダウンロードしても構わないでしょう。
ファイルサイズが小さければ。
数GB、数十GBあるファイルをFTP転送するのに15分かかるとすると、2回の転送で30分かかってしまいます。
回線が細くて30分かかるとすると、休憩してしまって終わったのに気づかないでさらにのんびり時間をロスする失敗を犯しそうで(※2)、ほんとに早く終わらせたい。
ですので、サーバー上からftpコマンドを実行し(※1)、移転元から移転先へ直接FTP送信します。

※1 sshが使えるのでscpがいいという方はもう、自由にそうしちゃってください。
※2 昔、夜間処理1回目の実行監視時に寝てしまって異常終了一歩手前であやうく回避したのを思い出して汗かいてしまいます。私だけかもしれませんが。

最近ではftpコマンドがインストールされておらず、lftpコマンドしか無い場合もありますが、どちらでも作業できます。
コマンドの使い方はちょっと異なりますがちょっとしか異なりません。

■ftpコマンドの場合

ユーザー名とパスワードは対話的に入力します。
Name で入力待ちになるのでユーザー名を入力し、331 Password required for dist_user の後にパスワードを入力します。
ユーザー名の次にパスワードを入れる、と理解してれば大丈夫です。
※で注釈のある個所が、入力する箇所です

ftp dist.example.com ※移転先にFTP接続
Connected to dist.example.com (xxx.xxx.xxx.xxx).
220 FTP Server ready.
Name (dist.example.com:src_user):dist_user ※ユーザー名を入力
331 Password required for dist_pass ※パスワードを入力
230 User dist_user logged in.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd /dist ※移転先で/distディレクトリに移動
250 CWD command successful
ftp> put public_html.tar.gz ※移転先に public_html.tar.gz を送信
local: public_html.tar.gz remote: public_html.tar.gz
227 Entering Passive Mode (xxx,xxx,xxx,xxx,xxx,xxx).
150 Opening BINARY mode data connection for public_html.tar.gz
226 Transfer complete
156 bytes sent in xx.xxxx secs (x.00 Kbytes/sec)
ftp> put src_database_name.dump.gz ※移転先に src_database_name.dump.gz を送信
local: src_database_name.dump.gz remote: src_database_name.dump.gz
227 Entering Passive Mode (xxx,xxx,xxx,xxx,xxx,xxx).
150 Opening BINARY mode data connection for src_database_name.dump.gz
226 Transfer complete
156 bytes sent in xx.xxxx secs (x.00 Kbytes/sec)
ftp> bye ※FTP接続を終了
221 Goodbye.

長いですね。
ほとんどコマンドが吐いているものですが。
ftpコマンドは古いというか、さびしがりやというか、対話が好きで避けられないんです・・・
説明は上記コマンド中にあるので割愛します。

■lftpコマンドの場合

次にlftpの場合です。

lftp -u dist_user,dist_pass dist.example.com ※移転先にFTP接続
lftp dist_user@dist.example.com:~> cd /dist ※移転先で/distディレクトリに移動
lftp dist_user@dist.example.com:/dist> put public_html.tar.gz ※移転先に public_html.tar.gz を送信
xxxxx bytes transferred
lftp dist_user@dist.example.com:/dist> put src_database_name.dump.gz ※移転先に src_database_name.dump.gz を送信
xxxxx bytes transferred
lftp dist_user@dist.example.com:/dist> bye ※FTP接続を終了

一見シンプル。
あなたも ftp ではなく lftp を使いたくなったことでしょう。
しかし、接続時のオプション -u とかユーザー名とパスワードをカンマ区切りとか、覚えておく自信がない・・・という方はある程度対話的にもログインできますので、調べてみてください。
ログインしてからの操作は(今回は)どちらも同じです。

さて、移転元から全てのデータを移転先に送ったので、移転元での操作は終了です。
誤操作を避けるために、一旦接続元へのssh接続を終了してください。
sshクライアントアプリで「接続終了」などのボタンを押してもいいでしょうし、コマンドでexitと入力しても接続を終了できます。

圧縮ファイルが残っていますが、今はこれは残しておきます。
リトライが必要になった場合に使うことができます。
消す必要があるなら、すべてうまくいった後に消すといいでしょう。

4.転送された圧縮済ファイルを解凍・配置

4-1.移転先への接続

ここから移転先の作業ですので、
そして転送先にssh接続しなおして、先ほど転送したファイルに対する操作をします。

cd /dist
ls -a ※/dist内のディレクトリとファイルの一覧を表示します。
public_html ※移転先サーバーのWebドキュメントルート
public_html.tar.gz ※FTP転送した、圧縮済みWebファイル
src_database_name.dump.gz ※FTP転送し、圧縮済みデータベースファイル

FTP転送したファイルが無い場合は、どこか別の場所にFTPしてしまった可能性があります。
一番ありそうなのは、FTP時にcd /distしなかった、あるいはディレクトリ名を間違えてエラーが出ていたのに気づかなかったために、ユーザーのホームディレクトリにFTPしてしまったケースです。
ホームディレクトリに移動し、/dist にファイルを移動することもできますが、ここではこの手順は割愛します。

4-2.解凍

移転先のドキュメントルートのディレクトリがすでに存在する様子ですね。
このままpublic_html.tar.gzを解凍すると、このディレクトリに上書きして解凍してくれます。
念のために、public_htmlの中に何も無いか、消して良いファイルしか無いことを確認しておきましょう。
このような確認作業はFTPクライアントからした方が楽かもしれませんが、そのソフトの設定によっては.htaccessなどのドットで始まるファイルが表示されないこともあるので注意が必要です。

ls -a public_html
.
..

何かドットだけが2行表示されました。
現在のディレクトリと親ディレクトリを示しているだけですので、無視してください。
何か覚えの無い、あるいは聞いていないファイルがあるときはサーバーの管理者に消して良いか聞いてください。

もしドキュメントルートのディレクトリが存在しない場合も、解凍すればpublic_htmlが作られます

Web関連ファイルを解凍します。
tar xvzf public_html.tar.gz
public_html/.htaccess
public_html/xmlrpc.php
public_html/wp-blog-header.php
public_html/readme.html
public_html/wp-signup.php
・
・
・
以下説明

xvzfxがtarアーカイブを展開するオプションです。

データベースのダンプファイルを展開します。
gzip -d src_database_name.dump.gz

何のファイルが出来たとも何とも言ってくれないですが、src_database_name.dumpというファイルが出来ています。
src_database_name.dump.gzは削除されていますが、そういうコマンドなのであせらなくても大丈夫です。

以下説明

gzipは圧縮にも展開にも使えるコマンドです。
-dが展開するオプションです。

5.データベースダンプをデータベースにインポート

先ほど解凍してできたデータベースダンプファイルsrc_database_name.dumpをインポートします。

mysql --default-character-set=utf8mb4 -h dist_database_host_name -u dist_database_user_name -pdist_database_user_password < src_database_name.dump

オプションはmysqldumpとほとんど同じなので解説はありません。

6.wp-config.phpのデータベース設定変更

web関連ファイルも正しい位置に配置され、データベースにデータも投入されたので、wp-config.php のデータベース接続先を変更し、いましがたインポートしたデータを使うように設定します。

vi public_html/wp-config.php

変更箇所は以下の通りです。

変更前 変更後
データベース名 define(‘DB_NAME’, ‘src_database_name’); define(‘DB_NAME’, ‘dist_database_name’);
データベースのユーザー名 define(‘DB_USER’, ‘src_database_user_name’); define(‘DB_USER’, ‘dist_database_user_name’);
データベースのパスワード define(‘DB_PASSWORD’, ‘src_database_user_password’); define(‘DB_PASSWORD’, ‘dist_database_user_password’);
MySQL のホスト名 define(‘DB_PASSWORD’, ‘src_database_host_name’); define(‘DB_PASSWORD’, ‘dist_database_host_name’);

この表タイトルの記述は、wp-config.php の日本語ファイルのコメントに合わせています。

以下説明

viって何だ・・・
エディタです。
リンク先は Vim のWikipediaですが、それがなぜかも含めてWikipediaを見て頂くとして、ここではエディタの使い方は説明しません。
もし emacs など他のエディタが得意ならそれを使ってもいいでしょうし、FTPクライアントが使える環境なのでFTPしてローカルで書き換えても良いと思います。
その際にWindows のメモ帳を使ってBOM付きのUTF-8で保存したりしないように気を付けてください。
改行コードをWindowsの改行コードにしても動きます。
後の人がファイルを開いた時に気持ち悪いですが。

変更したら、データベース内のホスト名を書き換えます。

7.データベース内のホスト名(など)を変更

もし、以下の条件を満たしていれば、この作業は必要がありません。

・サーバーを移転するだけで、ホスト名(URL)は同じ
・SSL化しておらず、URLはhttp://で始まる

そうでない方はそれなりに手間がかかります。

Search Replace DB をインストールさせてもらえるので、移転先サイトの public_html 配下にSearch Replace DB をFTPしてブラウザからアクセスしてください。
ここまで書いてきてちょっと根気が無くなってきたのもあり、使い方は検索すればいくらでも出てきます。
そのうち Search Replace DB の説明も書くかもしれません。

以下説明

https://でもURLが同じなら変更しなくて良いじゃないか、と思われた方。
SSL証明書は、DNSが切り替わっていないと取得することができません。
ですので、

  • DNSを変更し、世間に行き渡るまで待つ(数十分~数時間、もしくはそれ以上)
  • SSL証明書の発行を申請
  • 発行されたSSL証明書をインストール

とやっている間、新しいサーバーではhttps://でアクセスすると、「この接続ではプライバシーが保護されません」などと表示され、サイトにアクセスできなくなってしまいます。

Let’s Encrypt を certbot で運用されている場合などは、
・SSL証明書の発行を申請
・発行されたSSL証明書をインストール
という時間はほとんどかからず、DNS変更の反映時間はご自身の個人ブログやアクセスがそれほど多くないサイトでは、無視できるかもしれません。

レンタルサーバーでサイトを運用している場合には、Let’s Encrypt を使用していても
「SSL証明書の反映には最短でも1時間程度かかります」
とか言われたりもしますし、実在証明が必要などとなってきては数日を要す場合もあります。

この間、サイトにアクセスできなくてもいいのなら良いですが、http://であっても最低限、表示されないと困るのであれば、一旦、http://で始まるURLに変更しておき、SSL証明書発行後に再度、https://で始まるURLに変更する必要があります

8.アクセスしてみる

ブラウザでアクセスしてみましょう。
とにもかくにもサイトが表示された方、おめでとうございます。
データベース接続確立エラー(Error establishing a database connection)が表示された方、wp-config.php に記入したデータベース設定を間違えているか、事前に準備したデータベース接続情報自体が間違っている可能性が大いにあります。

レンタルサーバーで無い場合、ごくまれに、ネットワーク上、Webサーバーからデータベースサーバーへ接続できなかった、データベースサーバーが起動していなかった、などのケースも考えられます。

http:// でアクセスしているのに自動的に https:// での接続になり、この接続ではプライバシーが保護されませんと表示される方、.htaccess に https:// へリダイレクトする記述があるかもしれません。
.htaccess 中の該当行先頭に#をつけて(一時的に)無効化してください。
SSL証明書がインストールされたら、#を削除して再度有効化しましょう。
.htaccess の行を無効化しても改善しない場合は、ブラウザがキャッシュしているかもしれません。
キャッシュを削除するか、他のブラウザで試してみてください。

大成功してお客様にも確認してもらったら、移転元や移転先の圧縮ファイルを削除するのを忘れずに。

最後に

コマンドラインをほとんど使ったことが無い方が、ここに書かれていることを実行するのには勇気がいるかもしれません。
コマンドを入力して
command not found
と言われようものなら(ここで実行しているコマンドはほぼ全ての UNIX/Linux サーバーにインストールされていると思いますが)、どのような代替手段を使えば良いのか、考えることもできないかもしれません。

しかしまぁ、普段プラグインを使って移転作業されている方で何か今回はプラグインがエラーになってどうにもこうにも動かなかったりする場合や、ダンプファイルがデカすぎて phpMyAdmin にアップロードできない場合のお守りとして、いろいろ無くても最終的にはやれるかもしれない、と覚えておくといいかもしれません。

※とでも思わないと、頑張って書いた私の努力が報われない気がします。