開発室ブログ

Wordpress

WordPressでPostのプレビュー用途に最適なDBの同期方法

札幌もすっかり春めいてきまして、気温がマイナスになることもなくなりました。
春になると何か新しいことを始めてみたくなる・・・のは人の性、、、というわけで、私の場合以下の3つが毎年上がる「始めるべきこと」なのですが・・・

  • 英会話
  • ピアノ
  • (何か競技性のある)スポーツ

始めた試しがありません。
「じゃあ、載せなくてイイんじゃ・・・」という心の声が聞こえてもきましたが、ブログに書いておくと多少~は自分自身を焚付けられるんじゃないかと。

「やろう!」と思ったことを中々実現できない性質は子供の頃からだと自覚してますが、色々調べていくうちに、自分自身でオプションを付加し、ハードルを上げまくって実現可能性を低めてしまう~
というのがアンチパターンとして定着しています。
例えば、英会話の例だと・・・

  1. ビジネスにも活かしたい
  2. 発音にはこだわりたい
  3. 洋書の専門書を読めるようになりたい
  4. 英語圏に旅行に行って当地のパブで地元民と語らいたい
  5. いっそ海外で暮らしてみたい

等々、オプションが増えてハードルが上がっていくわけです・・・

Liverpool

画像は、「私が行ってみたい英語圏の都市No.1」 リヴァプール ですね。言わずもがなですが・・・
但し、リヴァプール辺りの所謂「スカウス(訛り)」は、他地域のネイティブ英語話者でもマジ聞き取り困難らしいですw(またハードルが上がった・・・)


以前、 「WordPressでステージング環境を利用して開発っぽい開発を志向する」 というテーマでブログを書いた際、

「WordPressでPostのプレビュー用途に最適なDBの同期方法」
といったようなテーマでまたの機会にPostしたいと思います~(汗)

と、書いてしまったので、「書かなくちゃ~書かなくちゃ~」と思ってはいましたが、

私たちの部署ではプロダクションレベルでWordPressを利用することは正直あまりないのですが

とか、言っちゃってましたので、後回しにしてましたw

WordPressでステージング環境を利用して開発っぽい開発を志向する|開発室ブログ|株式会社アクセスジャパン

最近、とあるプロダクションで、「ステージング環境のwpに承認フローを付けて、承認されたら本番環境にリアルタイムでデプロイ」と言った感じのソリューションを作りまして、それが望外に上手く運用できておりますもので、
「これは載せるしか無い~」
というわけで、当初考えてた方向性とちょっと(いや、かなり)違うのですが、今回やっと「以前に書いたPostの続編」を書いてみました(=「やろう!」と思ったことを実現しました!)。

シェルスクリプトの概念的なものとサンプルコード

やっと本題です。 まず、シェル(bash)でデプロイとテーブルインポートを実現させます。

以下

  • ステージング環境のドメイン=dev.example.com
  • 本番環境のドメイン=example.com

としてハナシを進めます。

1.ステージング環境のuploadsディレクトリをrsyncで本番環境に飛ばす

wpの管理画面からPostした画像は、通常wp-content/uploadsディレクトリにUPされますので、ここをrsyncコマンドで本番環境にデプロイします。

# rsync -{options} user@example.com:/var/www/vhosts/dev.example.com/wp-content/uploads/ /var/www/vhosts/example.com/wp-content/uploads/

削除オプション--deleteを付けておくと、単なるデプロイじゃなく、ステージングとの同期になりますね。

2.ステージング環境のDBをwp search-replace

矢庭に見慣れないコマンドが出てきましたがwp search-replacewp-cliの機能です。

Command line interface for WordPress | WP-CLI

簡単に言ってしまうと、

Aにインストールされたwpのdbのデータを、B用にドメインが書かれたレコードのドメイン部分を置換してダンプファイルを作成

するコマンドです。

# cd /sta/wp/install/dir
# wp search-replace 'http://dev.example.com' 'http://example.com' wp_* --export=dump_{datetime}.sql

と、このように使います。
wp_*の部分のように、対象にするテーブルをワイルドカードを使って指定が可能!
複数のブログを1つのdbでホストしてる場合等に有り難い機能ですね~

dump_{datetime}.sqlというファイル名は、「識別子代わりに日付の入ったファイル名にしとけば良いんじゃね?」的な発想からです。 実際はシェルスクリプト内で日時を変数に代入し、それを展開してファイル名にしてます。

wp search-replace | WordPress Developer Resources

wpではレコード内にURLが直書きしてあるケースが、、、結構多いので、結局こういう手順が必要になりますね。

3.#2)で出来たSQLファイルをscpコマンドで移動

先程はrsyncコマンドを使いましたが、今度はファイルUPだけが目的なので、scpコマンドを使います(scpコマンドは主にローカル< ->リモート間のファイルの上げ下げに使いますけどね・・・)。

# scp dump_{datetime}.sql user@$example.com:example.com/wp/install/dir/

本当は、当社の場合、ほほ全てのケースで鍵認証を使いますが、概念の説明なので-iオプション等は割愛してます。

4.本番環境に移動されたSQLファイルをインポート

今度はsshコマンドで本番環境にログインし、wpのインストールディレクトリまで移動して、wp db importコマンドを走らせます。

# ssh user@example.com
# cd /prd/wp/install/dir
# wp db import dump_{datetime}.sql

これで、必要なファイルとdbの同期が完了します。

5.SQLファイルを削除(本番環境とステージング環境双方とも)

最後に、エクスポート/インポートしたダンプファイルを削除します。

ssh接続はそのままに、

# rm -r dump_{datetime}.sql
# exit

で、インポートに使ったダンプファイルを削除し、
(サンプルでは分かりづらいですが)exitssh接続を抜け、ステージング側のエクスポートされたファイルも削除します。

# rm -r dump_{datetime}.sql

特に、ステージング側のエクスポートされたファイルは消しておかないと、次回実行時にwp search-replaceコマンドがエラーを吐きます(吐きました)。
ちゃんと公式のドキュメントを読めば解ると思いますが(まだ英語が読み書きできないので・・・)一定時間、エクスポートの結果がキャッシュされ、wp search-repladeを連発出来ないようにする(負荷が高い&クエリで遅延して整合性が取れなくなるのを防ぐ)抑止機能なのかな~と思ってます。

運用方法

件の「とあるプロダクション」では、これらの一連の流れをシェルスクリプト1ファイルで実現しているわけですが、実はwp用ツールwordmoveってのがありまして・・・

welaika/wordmove: Multi-stage command line deploy/mirroring and task runner for WordPress

これはruby製なので、、、rubyインストールしなきゃいけないし~
しかし、ドキュメント見た感じインストールするだけで大抵のことが出来てしまうようですので、vagrantvccw)等のローカル環境から、本番環境に一撃で移行~とかの場合は、こういったツールを利用させていただいた方が良いかと思います。

私達の場合(まだやってませんけど)お手製のシェルスクリプトをベースに、jenkins噛ましてCIを意識した運用~等もゆくゆくは検証してみたいと思ってます。

RecentPost