さくらのVPSから Lightsail へ引っ越した

さくらのVPSを使ってこのサイトをホスティングしてきた のだが、この度 AWS の Lightsail に引っ越した。

引っ越しした最大の理由は、契約して以降長らく使いっぱなしのマシンの OS が CentOS 6 だったから。 CentOS 6 は11月30日でサポートが終了 しており、そのまま運用するわけにもいかないぞ…と目下の課題だった。
それに、さくらのVPSを使っていたことには積極的な理由はなく惰性でそうしていただけだ。2020年12月時点でこのサイトのホスティングと、likealunatic.jp ドメインに紐づいたメールアドレスを Gmail に転送することにしか利用していなかった。メールは現在 Gmail のアドレスしか使っていないので、独自ドメインのメールアドレスは捨てることにした。引越し先では WordPress サイトのホスティングだけできればよい。

移転先として Lightsail を選んだのは、現在の仕事で AWS を利用しているため、少しでもサービスに触る機会を増やしたかったから。まあ、業務で Lightsail は使わないわけだけど…。それに調べてみると Lightsail の方がさくらのVPSよりコストが安いし、スペックも見劣りすることもなかったので。

年末年始の宿題として取り組むつもりだったのだが、思いのほか簡単に済んでしまって拍子抜けだった。

ほぼ こちらの記事([Lightsail]さくらインターネットからAWS LightsailにWordPressを最速で移行する – スモールスタート編 | ma-ya’s CREATE / WEB DESIGN) で紹介されている手順で作業は完了した。とても有用な記事をありがとうございます。

つまづいたポイントとしては HTTPS 化の作業で sudo /opt/bitnami/bncert-tool した際に、

Warning: The domain 'mydomain.com' resolves to a different IP address than the
one detected for this machine, which is 'aa.bb.ccc.dddd'. Please fix its DNS
entries or remove it. For more info see:
https://docs.bitnami.com/general/faq/configuration/configure-custom-domain/

というようなメッセージが表示され、それ以上設定が進められなくなったこと。 これはドメインのゾーン情報に、旧サーバーを指すAレコードが残っているからだった。さくらインターネット会員メニューのドメイン設定画面からAレコードを削除したら解決。

というわけで2021年も始まりましたが、こちらはのらりくらりとやっていこうと思っています。 改めまして、明けましておめでとうございます。本年もよろしくお願いいたします。

References

Noto Serif CJK JP を Web フォントとして使う

仕事で明朝体のサイトを作ることになったので Noto Serif CJK が Web フォントとして使えないか、と調査した。 Noto Sans JP は CDN 配信されている が、Noto Serif JP は配信されていないので、自前でファイルを持つ必要があるのだ。これはめんどくさいぞ…。

まずは Noto CJK – Google Noto Fonts の “Region-specific Subset OpenType/CFF (Subset OTF)” というセクションから使いたいウェイトをダウンロード。今回は NotoSerifCJK-Regular.ttc を選択した。

Web フォントとして使用するために ttc ファイルを woff2 と woff に変換する。今回は WOFFコンバータ を使うことにした。 できたデモがこちら。

NotoSerifCJK-Regular をWeb フォントとして使用するデモ

ファイルサイズは woff2 で 4.5 MB、woff で 5.2 MB だ。これでも “Regision-specific Subset” とサブセット化されているものだが、まだ実用に耐えうるサイズじゃない。Chrome のネットワークエミュレーションで “Fast 3G” を選択するとダウンロードするのに 24.51 秒かかる。ちなみに通常の環境(光+Wifi)だと 674 ミリ秒。うーむ。

Noto Serif JP - 単にwoffに変換した状態

というわけでさらなるサブセット化に取り組むことにする。これには サブセットフォントメーカー を使う。 ネット検索し、「第一水準漢字+記号+ローマ字+カタカナ+ひらがな」のソースを探すが、信頼に足るものがいまいち見つからない。

まずはこちらさんを試す。 ん、なんだか漢字少なすぎじゃない?

Noto Serif JP - サブセット化1

ではこちらさんはどうだろう。 えぇ…、「j」がないよ…。

Noto Serif JP - サブセット化2

で、結局、漢字のセクションだけ後者、それ以外を前者から頂戴する形でサブセット化。 うむ。まぁこれでよかろう。

Noto Serif JP - サブセット化3

サーバーにアップロードして、と。

サブセット化した NotoSerifCJK-Regular を使用するデモ

Chrome DevTools で同じ条件(Fast 3G)で見てみると…、3.87秒。及第点じゃないだろうか。

Noto Serif JP - Noto Serif JP - サブセット化した後の計測

本日はこの辺で。

References

Articles

Resources

Let’s Encrypt でサイトの SSL 化

Let’s Entrypt という素晴らしいサービスが無料のSSL証明書が提供していると同僚に教えてもらったので、試しにこのサイトに導入することにしました。
このエントリーは導入過程のメモです。

Let’s Encrypt は Certbot というコマンドラインインターフェースを持っていて、証明書の取得とインストール、更新までコマンドでできるようになっているとのこと。なんとまあ便利ですね。

証明書の有効期限は90日間しかないので、crontab などで有効期限前に自動で更新していく運用が望ましいみたいです。ではそうしていきましょう。

事前に以下の準備をしておきます。

  • Really Simple SSL プラグインを WordPress にインストールしておく
  • ファイヤーウォールがあるならインバウンド 443 ポートを開けておく

また、環境としてはさくらのVPS(CentOS 6)で Nginx + WordPress を動かしている状態です。

証明書のインストールとWebサーバーの設定

サーバーに SSH でログインして、作業開始。
certbot-auto スクリプトをダウンロードして、 /usr/bin に移動、実行権限をつけて、実行。ウェブサーバーは Nginx なので、--nginx オプションをつける。

$ wget https://dl.eff.org/certbot-auto
$ sudo mv ./certbot-auto /usr/bin/certbot-auto
$ sudo chmod a+x /usr/bin/certbot-auto
$ sudo certbot-auto --nginx

これでインストールウィザードが始まる。 以下のくだりでは「2」と答えておくと、Nginx 設定ファイルにリダイレクトの設定を勝手に書き込んでくれる。

Please choose whether HTTPS access is required or optional.
-------------------------------------------------------------------------------
1: Easy - Allow both HTTP and HTTPS access to these sites
2: Secure - Make all requests redirect to secure HTTPS access
-------------------------------------------------------------------------------

設定を反映させる。

$ sudo service nginx reload

この状態でもうすでにSSL化はできていた。https でサイトにアクセスしてみると以下のような状況。

SSL証明書を表示確認しているところ

http 接続を https 接続に強制リダイレクトをかける。
certbot-auto が /etc/nginx/conf.d/default.conf に設定を書き込んでいるが、コメントアウトされているのでそれを外して有効にする。

     # Redirect non-https traffic to https
-    # if ($scheme != "https") {
-    #     return 301 https://$host$request_uri;
-    # } # managed by Certbot
+    if ($scheme != "https") {
+        return 301 https://$host$request_uri;
+    } # managed by Certbot

設定を反映させる。

$ sudo service nginx reload

最後に自動更新の設定。
毎週日曜日の5時に更新処理が走るように設定した例。

$ sudo crontab -e

0 5 * * 0 certbot-auto renew --post-hook "service nginx reload" >/dev/null 2>&1

Really Simple SSL プラグインを使う

インストールしてアクティベートすると以下のようなメッセージが表示される。

Relly Simple SSL Plugin

「Go ahead, activate SSL!」ボタンを押す。すると以下のようなメッセージが表示される。

SSL activated!  Don't forget to change your settings in Google Analytics en Webmaster tools.  More info.

えっと…、本当に簡単だな…。
Google Analytics と Webmaster tools の面倒も見ろとな。あとでね。

以上です。


P.S.

URLが変わるので、はてブ数などはリセットされてしまいます。まぁそれはそうだわな。
本文「likealunatic.jp」を検索 - はてなブックマーク


References

webpack にまつわるぐだぐだ。キャッシュ対策と CommonsChunkPlugin

webpack (version 2) の公式ドキュメントではバンドルファイルのブラウザキャッシュ対策として、ファイル名にハッシュ値を埋め込む方法が提案されている

こうするとアプリのコードを変更する度に、バンドルファイル名に埋め込まれたハッシュ値も更新され、ブラウザキャッシュ対策ができる、という寸法だが…。
当然ファイル名が変わるわけだから、<sript> タグも更新しなくてはならない。それを解決するには、HTML ファイルも動的に扱わなければならない。chunk-manifest-webpack-pluginhtml-webpack-plugin を導入し、HTML のテンプレーティングを行い…、となると今使っている Pug はどうなる…、となってさらにさらに掘り下げないといけなくなり、はっきり言ってソリューションとして無理がある。

閑話休題。

webpack をヘビーに使っていると、サードパーティーフレームワークやライブラリのコード(npm install でインストールしたようなモジュール)を出力ファイル(バンドルファイル)から切り離したくなる。 バンドルファイルにライブラリが直接含まれるが故に、以下のような事象に直面したことがある開発者は多いのではないだろうか。

  • 複数人で開発していて各自のライブラリのバージョンが微妙に異なり、Git経由でやり取りされるバンドルファイルに環境の差分までが含まれてしまう
  • 使っているライブラリが増えて、コンパイルがとても遅くなる

解決策として、フレームワークやライブラリはまとめて別のバンドルファイルにする、もしくは単独で配布されたものを <script> タグを読み込む、という解決方法を取ることもできる。 これを可能にするのが externals オプションで、ここで宣言された名前については、依存関係がグローバルスコープから参照されるようになる。

externals: {
  jquery: 'jQuery'
}

webpack.config.js に設定しておくと、 import jQuery from 'jquery'; というコードはグローバルスコープの jQuery を参照するようになり、バンドルファイルに jQuery のコードは含まれないようになる。 もちろんこの場合には jQuery は新たに別の <script> タグで読み込む必要ある。

よりスマートな解決策としての CommonsChunkPlugin

CommonsChunkPlugin を使うと、複数のバンドルファイルから共通の依存モジュールを切り出してくれる。 サードパーティーライブラリをアプリのコードと分割する、という使い方ももちろんできる。 公式で示されている設定は以下のようなものだ。

plugins: [
  new webpack.optimize.CommonsChunkPlugin({
    name: "vendor",
    minChunks: function(module){
      // node_modules のディレクトリ下に含まれるものだけに絞る
      return module.context && module.context.indexOf("node_modules") !== -1;
    }
  }),
  new webpack.optimize.CommonsChunkPlugin({
    name: "manifest", // 名前は "manifest" でないとダメ
    minChunks: Infinity // entryがいくつあろうと生成。省略可
  }),
]

サードパーティーコードを別にしたいだけなら vendor だけでも目的は果たせるが、manifest を入れると、webpack バンドル共通部分(ソースには webpackBootstrap とコメントが書かれている部分)が manifest.js として別ファイルに書き出される。こうするとビルドするたびに vendor のハッシュ値が変更されることを防げるとのこと。
でもこれ、先述のハッシュ値をファイル名に含めるキャッシュ対策をやっていないと、意味はなさそう。なぜならハッシュ値はバンドルファイルのコード内には現れないから。

manifest を定義した場合、以下のように manifest.js も読み込まないとコードは動かないので注意。

<script src="/js/manifest.js"></script>
<script src="/js/vendor.js"></script>
<script src="/js/bundle.js"></script>

References

WP Pusher による WordPress テーマの自動デプロイ

WP Pusher というプラグインを導入し、GitHub のレポジトリの master ブランチに push したらサイトの WordPress テーマが自動的に更新されるという運用にしてみた。

seckie/likealunatic: Like@Lunatic website source code

サイトの静的ファイルがテーマディレクトリの外に散在していた状態だったから、それもできなかったわけだ。今回自作テーマを大幅に整理したことで、テンプレートも静的ファイルもすべて1つのテーマフォルダに収めることができた。(まあ当たり前の状態になったというべきか…)

GitHub の Webhooks による自動更新は以前からやりたかったのだが、CI ツールを使ったことのない僕にはハードルが高かった。しかし調べてみると、プラグインでそういうものがある、という情報があった ので導入してみることにした。該当記事の紹介によると、ビルドを Travis CI で行い、その後 dist ブランチに自動的にプッシュ、それを Webhooks で拾って本番にデプロイ、というフローになっている。しかし僕の環境だとビルドはローカルでやっているので Travis CI を使うフローは不要になる。シンプルに GitHub と WP Pusher だけの形で実現できた。

ただしハマったポイントが一つある。

WP Pusher は公式プラグインディレクトリに置いていないので、FTP を使ってアップロードした。すると、該当ファイルとディレクトリのオーナーは当然その FTP ユーザーになる。それによってパーミッションの問題が発生。

このサイトは Nginx + WordPress で動作している。 Nginx を使っている場合、wp-content ディレクトリなどに対して nginx ユーザーに書き込み権限を与えておけば、 WordPress (PHP) から自動更新やらプラグインの追加削除が行えるようになる。そうでない場合、WordPress は FTP 経由でファイルを出し入れしようとして FTP 情報を入力するプロンプト画面を表示する。
WP Pusher による自動デプロイも例外ではなく、パーミッションが適切でないと WordPress がそのページを表示しようとしてしまい、正しく通信できないらしい。

ちなみにエラーは GitHub の 該当 Webhook のページ下方に “Recent Deliveries” というセクションがあるのでそこで確認できる。 Webhook を設定すると通信確認のためなのか Recent Deliveries に1つ通信が記録される。それがエラーになっていた場合、Response が “500” となっているはず。Body のセクションを確認すると「FTP credentials を入力してください」という感じの HTML が出力されている。

GitHub Webhook setting screen
これは正常な状態。

今回のケースでは wp-content 以下すべてのファイル、ディレクトリオーナーを nginx ユーザーに変更したら解決した。 ちなみにこのことは WP Pusher Troubleshooting のページにもちらっと記述があった…。なんだろうこの徒労感。

参考