中小企業のマーケティングやブランディングのコンサルティング。事業運営、組織運営のPDCA改善やホームページの制作、ウェブサイト改善などITネット活用を中心にサービスを提供しています。

WordPressをサーバH2Oで動かす (WordPressアプリケーションサーバとしてのH2O)

常時SSL とプロトコル HTTP/2 に対応するため、サーバ環境を新しくしてウェブサイトを移行しました。
新しい試みとしてサーバ構成を CentOS7 + PHP7 + MariaDB + H2O + WordPress にしてみました。

次世代の HTTPサーバ H2O を中心に速い WordPress を目指してサーバを構築。

今回 WordPress を HTTPサーバ H2O でどのように動かせばいいのか見てみたいと思います。

HTTPサーバ H2O とは

H2O は、プロトコル HTTP/2 に最適化されたウェブサーバです。

ここ数年でセキュリティ面で SSL が必須になりつつあり、ネット環境も新しい通信規約 (プロトコル) が求められている時代に最適なウェブサーバのひとつになっていくのだろうと注目していました。

H2O の開発は、2014年から元DNAの @kazuho さんが中心にオープンソースとして進められています。Perl を使っている方はウェブアプリを作るときに Server::Starter でお世話になっているのでは。ボクもいつもお世話になっています。
Server::Starter は、H2O のバックグラウンドにも使われていて start_server が動いているのが見て取れます。こういうところにも使われているのかとほんと感心しますね。

HTTP/2 時代を見据えているだけあってサーバの性能もベンチマークを見るとレスポンスが Apache や Nginx より速い。
他にも H2O の技術要素に注目したいものがたくさんあるのですが、詳しく知りたい方は、公式サイトやスライドも上がっているのでそちらを見ていただければと思います。

WordPress をサーバ H2O で動かす

2015年6月に FastCGI機能を実装したバージョン 1.3.0 がリリースされて、PHP が動くようになりました。
サーバ H2O で WordPress を動かすには、2 つの方法があります。

ひとつめは、WordPress を PHP-FPM や HHVM で管理。Nginx で従来やっている馴染みのあるやり方をそのまま踏襲。H2O も fastcgi.connect でホストに繋げてレスポンスを返してくれる。

今回採用したもう一個の方は、H2O 自体で管理する方法。
fastcgi.spawn で起動してH2Oの下で PHP のプロセスを管理してくれます。
PHP-FPM や HHVM をインストールしてコンフィグの設定起動、運用の手間がなくなります。

今回の試みとして思っていたことで、
WordPress とかPHPアプリを動かすアプリケーションサーバとしてH2Oは、最適なんじゃないかなぁと。

実際 H2O の下に php-cgi が動いているのが見て取れます。

WordPress を動かすサーバ設定 (/etc/h2o/h2o.conf) もYAML書式でシンプルに書けます。

以下これだけでWordPressが動きます。

paths:
  "/":
    file.dir: /path/to/wordpress
    redirect:
      url: /index.php/
      internal: YES
      status: 307
    file.custom-handler:
      extension: .php
      fastcgi.spawn: "PHP_FCGI_CHILDREN=10 exec /usr/bin/php-cgi"

実にシンプル。YAMLでわかりやすいのがいいですね。(本番運用には、自動更新やダッシュボードへのアクセスのところでもう少し手を入れる必要があるのですが。)

で今回の試したサーバ設定は、

  • 常時SSL
  • www にURL正規化
  • http から https にリダイレクト
  • WordPress ツールバーからダッシュボード (www.example.com/wp-admin/) へアクセス
  • WordPressの自動更新ができるように
  • FastCGI のスループットチューニング
  • 他もろもろ

で以下のような本番運用サーバ設定 (/etc/h2o/h2o.conf) になりました。

user: nobody
 
listen:
  port: 80
listen:
  port: 443
  ssl:
    certificate-file: /path/to/fullchain.pem
    key-file: /path/to/privkey.pem
 
hosts:
  "localhost":
    paths:
      "/":
      redirect:
        status: 301
        url: https://www.example.com/
 
  "www.example.com:80":
    paths:
    "/":
      redirect: https://www.example.com/
  "www.example.com:443":
    paths:
      "/":
        file.dir: /var/www/wordpress
        redirect:
          url: /index.php/
          internal: YES
          status: 307
 
file.index: [ 'index.php', 'index.html' ]
 
file.custom-handler:
  extension: .php
  fastcgi.spawn:
    command: "PHP_FCGI_CHILDREN=10 exec /usr/bin/php-cgi"
    user: example
  fastcgi.timeout.keepalive: 10000
 
access-log: "| exec sudo rotatelogs /var/log/h2o/access.log.%Y%m%d 86400"
error-log:  "| exec sudo rotatelogs /var/log/h2o/error.log.%Y%m%d 86400"
 
pid-file: /var/run/h2o/h2o.pid
http1-upgrade-to-http2: ON
http2-reprioritize-blocking-assets: ON

WordPressを動かすH2Oサーバ設定のポイント

WordPress ツールバーからダッシュボード (www.example.com/wp-admin/) へアクセス

通常の設定では、WordPress ツールバーからダッシュボード (www.example.com/wp-admin/) へアクセスは、トップページを返してしまいます。

ダッシュボードにアクセスできるように file.index で index.php を追加して www.example.com/wp-admin/ で www.example.com/wp-admin/index.php にアクセスするようにしました。

WordPressの自動更新ができるように

H2O はデフォルトで nobody の下で動きます。
H2Oの管理下にある PHP も nobody で動きます。
WordPressの自動更新は、WordPressのファイル所有者の下でPHPが動かないと自動更新が働きません。
fastcgi.spawn には、どのユーザ user で動かすか指定できるので、WordPressのファイル所有者を指定して動かします。

FastCGI のスループットチューニング

fastcgi.spawn での PHP への接続は、デフォルトでは1回限りの接続です。これだとWordPressが動くたびにコネクションが発生します。
fastcgi.timeout.keepalive で Keep-Aliveを 10 秒に指定。一定時間 FastCGI の接続を継続させてスループットを改善してみました。

まだまだキャッシュ周りやいろいろチューニングができそうなので、運営しつつ試してみたいと思います。

参考サイト

ブログを Movable Type から WordPress に移行

Movable Type から WordPress に移行したときの備忘録です。

このブログは、PSGI Plack 環境の Movable Type で運営してきました。
今回 WordPress の移行をどこまでできるか、開発環境でいろいろ試してみました。移行前に考えたのは…

  • コンテンツマネジメントシステム (CMS) は同じでサーバ間の移行は経験があるけど、CMS 間の違いの移行はやったことがない。
  • Movable Type はバージョン 5
  • CMS 間で形式が違うデータをどうやって WordPress に移行するのか。
  • どの程度コンテンツデータに手を入れる必要があるのか。
  • パーマネントリンクの URL は、すでに登録されている検索インデックスに影響を与えないようできるだけ維持したい。

まずは、データの移行

Movable Type のブログデータのエクスポート。
「ツール > 記事のエクスポート」からエクスポートしてテキスト形式のファイル (export-xxx.txt) をダウンロードします。

開発環境に構築していた WordPress にそのエクスポートファイルをインポートします。
「ツール > インポート」にある Movable Type と TypePad で「今すぐインストール」をクリックするとインポーターがインストールされます。インストールが完了して「インポーターの実行」をクリックすると、インポーター画面に移動。
実際は裏でプラグイン「Movable Type・TypePad インポートツール」をインストールして有効化されています。
移行が済んだら無効化しましょう。

インポーター画面では、
エクスポートファイルを選択する方法と、
エクスポートファイルを mt-export.txt に変えて /wp-content/ ディレクトリに直接アップロードする方法の
2 つのやり方があります。

今回は、エクスポートファイルのデータサイズが大きくないので、ファイルを選択する方で。

ダウンロードしたエクスポートファイルを選択して「ファイルをアップロードしてインポート」ボタンを押すと、
新しくユーザを作るか、今いるユーザに投稿者を割り当てて「実行」をします。

いたってスムーズにデータの移行ができました。

どこまでデータが移行できたか

タグは移行できなかった。タグはほとんど使っていないので問題ないけれど。
やる場合はプラグインに手を入れる必要がある。
画像がメディアライブラリに入ってくれたら嬉しかったけど。
エクスポートファイルとの対応付けの難しさ、
エクスポートしたデータを変更してしまうデータ保全から無理もない感じで。
実装が難しそう。

あとは問題ない。投稿もコメントもちゃんと入っている。

コンテンツデータに手を入れるとすれば、画像の張り替え。
いままでの画像フォルダを残しておけば、そのまま引き継がれる。
特段手を入れる必要は無いけれど。
今回は画像数が少ないので、メディアライブラリで管理することに。
コンテンツデータは画像のところだけ手を入れた。

パーマネントリンクのURLをどう維持するか

一番考えて調整が難しかったのがパーマネントリンクの引き継ぎ。
パーマリンクの構造は、Movable Type のテンプレートで設定していたアーカイブマッピングに依存してしまう。

ブログ記事のアーカイブパスは、archives/%e.html
%e は、6 桁のエントリー ID、桁数が 6 桁に満たないとき、0 で埋めて表示される。

ブログ記事リストでは
カテゴリが %c/index.html
月別は %y%m/index.html
とパーマリンクの構造を設定していた。

WordPress に設定するパーマリンク設定として、
ブログ記事は Movable Type から完璧に引き継ぎ。
これは記事が検索されることを考えると譲れないところ。
ただし、今後はパーマリンクを変更できるようにしたい。

カテゴリやアーカイブは、
プラグイン「Custom Permalinks」でカテゴリ、タグを個別にパーマリンクの設定ができるので、対応できる。
けれど、今後の運営のことも考えて WordPress のパーマリンクの構造に変更することにした。

ということで、パーマリンク設定のカスタム構造は、
投稿のスラッグを 6 桁のエントリー ID でヒモ付けて
パーマリンク設定のデフォルトの選択にはない以下の通りに設定した。

/archives/%postname%.html

記事のスラッグを 6 桁のエントリー ID に変える作業をやった。

これでいままでのパーマリンクを引き継ぎつつ、
今後はパーマリンクを自分でつけられるようにしてみました。

Blue-Green Deployment で無事に移行完了

あとは、メニューを作ったり、必要なプラグインを入れたりしてレイアウトを整えた。
本番環境のサーバーに新しい DocumentRoot を作って WordPress を入れてそこに WordMove で同期。
サーバーの設定を前のブログの DocumentRoot から 新しい方の DocumentRoot に向けて振り替え。
サーバーを再起動すると、WordPress ブログの運営が始まりました。
Blue-Green Deployment 的にデプロイを進めてみました。

ウェブサイトの移行は?

まだ試していない。ウェブサイトの移行も試してみたい。
普通はホームページのリニューアルを考えるものが大半だと思うので、正式なやり方がない。
そもそもCMS間でサイトの捉え方が違う。
Movable Type は、今までのサイト設計のようにフォルダーを作ってウェブサイトの設計ができるけれど、
WordPress は、固定ページを作ってそこに親子関係を作っていく設計をするので、
そこをエクスポートデータでどう吸収できるかがサイト移行の肝のような気がする。

WordPressプラグイン「Custom Post Type Widgets」に Search Widget を追加しました

カスタム投稿タイプで活用できるデフォルトウィジェット WordPressプラグイン「Custom Post Type Widgets」をアップデートしました。

今回のアップデートでは、新たに Search Widget を追加しました。

投稿、固定ページ、カスタム投稿タイプで絞り込み検索ができます。

また、Search Widget と Comments Widget には Custom Post Type すべてを対象にできるようにしてみました。

開発裏話

今回いろいろ手を入れて、ウィジェット独自にキャッシュ機能があったのを削除したり、全面的にリファクタリングをして、コード数もざっくり減らすことが出来ました。

一番悩んだことは、Search Widget は GitHub でプルリクをいただいたのですが、うまく機能しなかったこと。
書いたプラグインがダメではなく WordPress 本体の方。個別ページだけの検索絞り込みができない。

ググってもあまり分からず、WordPressで検索の絞り込みノウハウが書いてあるブログ記事を見てもなぜか投稿ページだけの絞り込みに関してはたくさんあるが、ページに関してはほとんどなかったり。

ということでソースコード (wp-includes/post.php) を読むと、個別ページを作成する register_post_type には、publicly_queryable に false が設定されており、フロントエンドで post_type クエリが実行できないようになっています。(なぜそうなっているのか開発フォーラムを見ても経緯がよく分からなかったのですが…)

実際、?post_type=page でアクセスしても post_type が破棄されて (unset)、裏で revision以外すべてのタイプ (any) が検索対象になったりします。

個別ページだけの検索絞り込みをするために対処したことは、検索ページが表示される時に、pre_get_posts にフックして破棄された post_type を再度追加してみました。

他のアプローチとしては、register_post_type で登録されたものを変更してもいいのではと思ったのですが、そもそも register_post_type を実行途中で変えていいのか、検索時だけなので影響範囲を考えるとこれでいいのではないかと。
また、register_post_type の変更方法がわからないというのもあります… 誰かどういうアプローチがあるのか教えてください。

おかげさまで

WordPressプラグイン「Custom Post Type Widgets」は2015年1月にリリースして一年あまり。海外の開発者に反応が良く、プルリクをいただいたり、段々使われるプラグインに育ちつつあります。カスタム投稿タイプを使ったテーマ開発に是非使ってみてくださいね。

ダウンロード & インストール

WordPress の公式プラグインページ

ライセンス

GNU General Public License v2.0 (GPLv2) licenses

開発

GitHub

ページの先頭へスムーズに戻る WordPressプラグイン「Back to the Top」をリリースしました

去年 2014年10月に jQuery プラグイン「Back to the Top」 をリリースしました。今回、そのWordPressプラグイン版をちょこちょこ作ってリリースしてみました。

jQueryプラグイン版は、jQueryを読み込んだり、HTMLを用意したりと、いろいろ設定が必要になります。オプションがたくさんあるのでカスタマイズが自在にできます。反面、設定が煩わしかったりします。

WordPressプラグイン版は、WordPressにインストールして有効化すると、もろもろデフォルトで設定してくれてそのまま使えます。カスタマイズもオプションページでプレビューを見ながらかんたんに設定できるように作ってみました。

カスタマイズは、ラベルに Webフォントを採用したアイコンが選べたり、スクロールの動き (easing) も。また、上級者向けにスタイルシートがカスタマイズできます。

インストールは、WordPressプラグインページから。または、管理画面のプラグインの新規追加から「Back to the Top」で検索してインストールできます。

WordPressプラグインのインストール方法は「プラグインをインストールする – WordPressマニュアル」を参考にどうぞ。

WordPressプラグイン「Jetpack」のCDN「Photon」をWordPressテーマ・プラグインに実装するスニペット

WordPress プラグイン「Jetpack」にCDN (Contents Delivery Network) で画像を配信する「Photon」があります。「Photon」を使うと、画像配信の分散ができ、サーバの負荷分散やサイトの表示パフォーマンスの向上に繋がります。

「Photon」 は、WordPress.com で使われていたり、自分でホストしている WordPress サイトにプラグイン「Jetpack」をインストールすることで導入できます。

「Photon」の導入は、プラグイン「Jetpack」の「Photon」を有効化するだけで CDN で画像配信されます。

画像配信されるのは、サムネイル画像やアイキャッチ画像だけで、「Photon」で配信されない画像もあります。たとえば、ご自身でテーマやプラグインをカスタマイズしたり、開発した場合。img タグで埋め込んだりすると、画像が「Photon」に対応した形にならないのでうまく配信されません。こういう場合も Photon API が用意されているので、対応ができます。

以下のスニペットで 「Photon」を有効化していると、画像URLを元に Photon用URL を生成して画像配信してくれます。

$image_url = class_exists( 'Jetpack' ) && method_exists( 'Jetpack', 'get_active_modules' ) && in_array( 'photon', Jetpack::get_active_modules() ) ? 'http://i' . mt_rand( 0, 2 ) . '.wp.com/' . str_replace( array( 'http://', 'https://' ), '', esc_attr( $image_url ) ) : esc_attr( $image_url );

「Photon」を利用する場合、WordPress.com を使っているか、WordPress サイトにプラグイン「Jetpack」をインストールしている場合に限りますと、利用規約にあるのでご注意を。