OTOBANK Engineering Blog

オトバンクはコンテンツが大好きなエンジニアを募集しています!

CircleCI で Hugo を使う

もう 3 月も終わりそうですが、本当に終われるのでしょうか... @riaf です。

突然ですが、ちょっとした静的なページを用意したいなっていうこと、わりとありますよね。 いつもはだいたい GitHub Pages (+Jekyll) とか使ったりすることも多いんですが、今回は簡単にテーマを編集したりしたかった (り、ブログのネタが欲しかったりした) ので、シンプルな作りで爆速な Hugo を使ってみることにしました。

最終的には、以下のような構成で動かそうという目論見です。

  1. Github リポジトリに push
  2. CircleCI が Hugo でジェネレート
  3. IDCF クラウドのオブジェクトストレージ (S3 っぽいやつ) でホスティング

CircleCI で Hugo を使うためにはまずインストールする必要があります。が、ここで go get とかしちゃうと負けた気持ちになるので、もっとシンプルにインストールしてみます。 最初はビルド済みのバイナリを落としてきて実行しようと考えていたんですが、Hugo の releases を見ると、deb ファイルも用意されていたので、これを使ってみることにしました。

Circle CI では、sudo が使えるので、パッケージのインストールも以下のように書けます。

dependencies:
  pre:
    - wget https://github.com/spf13/hugo/releases/download/v0.15/hugo_0.15_amd64.deb
    - sudo dpkg -i hugo_0.15_amd64.deb

Hugo のインストールさえ済んでしまえばあとは簡単ですね。 実際にビルドできるかどうかを試す、という意味では test に入れちゃってもいいのかもしれませんね...。

test:
  override:
    - hugo

本題はこれで終わりなんですが、今回は IDCF のオブジェクトストレージに配布したかったので以下のようにしました。

dependencies:
  override:
    - pip install awscli
    
deployment:
    production:
        branch: master
        commands:
            - aws --endpoint-url http://ds.jp-east.idcfcloud.com s3 sync --acl public-read --delete public/ s3://[Bucket name]/

aws コマンド実行のために、CircleCI の環境変数に AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY を設定してあります。

そしてこれを IDCF のコンテンツキャッシュに入れて...とかやりたいんですが、オブジェクトストレージには S3 のようなインデックスドキュメントのサポート がありません。 仕方がないので、フロントに nginx をおくことにします。

簡単に書くと、こういうことを nginx でやる感じです。

server {
    server_name example.com;
    rewrite ^(.+)?/$ "${uri}index.html";

    location / {
        proxy_ignore_headers Cache-Control;
        proxy_pass http://example.com.ds.jp-east.idcfcloud.com/;
        add_header Cache-Control public;
    }
}

なんだか Hugo があっさり使えてしまったので、IDCF クラウドへのデプロイで苦戦した話みたいになっちゃってますが、これで当初の目的は達成できました!

めでたしめでたし

おまけ

ただですね、上の構成だけだと IDCF のオブジェクトスレージがあまり速くないせいかレスポンスに 1sec くらいかかる静的ページができてしまうので、Nginx の方でキャッシュするとか、さらに CDN かませるとかしたい感じになります。

ページの更新時にキャッシュもクリアしたい。とかを考えて、Cloudflare も試してみました。 (ついでに HTTPS もゲットだ!)

Cloudflare でデプロイ時にキャッシュを削除をするために、circle.yml で以下のように書いてみました。aws コマンドの実行後に追加します。

- curl -X DELETE https://api.cloudflare.com/client/v4/zones/{YOUR ZONE ID}/purge_cache -H "X-Auth-Email:{YOUR EMAIL}" -H "X-Auth-Key:{YOUR AUTH KEY}" -H "Content-Type:application/json" --data '{"purge_everything":true}'

これでアクセス増にも耐えられる、メンテナンスがそれなりに楽な仕組みができましたね! (そもそも Hugo + Github Pages にしておけばこんなことにはなってないわけですが...)