wktk.jp

ブログ (GatsbyJS) を Netlify から Firebase Hosting に移した

2020-06-10 00:20:00

背景

このブログは今まで Gatsby で生成して Netlify でホストしていた

最近、はてな ID と紐付け の設定をするため、 <link rel="author" href="..." /> のタグを埋め込もうとしていた。 はてな側の仕様上、この href は http:// から始まる必要がある様子である。

しかし、Netlify の mixed content detection が誤反応して自動で https:// に置き換わってしまう。 さらに、これを無効化する手段がない。

Netlify の日本からのレイテンシも気になっていたのと、Firebase を使ってみたかったので、本番を Firebase に移設することにした。 ただし、Netlify の Pull request のプレビュー機能が便利なので、Netlify の設定は残しておく。

対応内容

概ね 一般的な手順 で移行できた。 新規に、HTTP リダイレクトの自動生成と、GitHub Actions での自動デプロイを対応した。

HTTP リダイレクトの自動生成

Netlify では、gastby-plugin-netlify を入れておけば Netlify の仕様 に合わせて public/_redirects が生成され、 HTTP リダイレクトが行えた。

Firebase では firebase.json に記述する必要がある。 当サイトではリダイレクトを動的に生成しているので、firebase.json への記述は煩わしい。

そこでとりあえず、gastby-plugin-netlify が生成する public/_redirects ファイルをデプロイ時に力技で firebase.json に反映することにした。 下記のコマンドで firebase.json に結合させている。

grep -v -e '^#' -e '^http' public/_redirects \
  | jq -nR '{hosting: {redirects: [inputs | select(length>0)] | map(split("  ")) | map({"source": .[0], "destination": .[1], "type": .[2]})}}' \
  | jq -s '.[0] * .[1]' firebase.json - \
  > firebase.json.tmp
rm firebase.json
mv firebase.json.tmp firebase.json

GitHub Actions で自動デプロイ

Netlify では GitHub からの CD 機能を内蔵していて簡単だったが、Firebase では firebase deploy コマンドを経由する。

自動デプロイの設定ファイルは、移植性を確保するために実際の処理内容を極力 Makefile に記述している。 YAML はサービス上で make deploy を動かすためのアダプターの役割に徹する棲み分けを図っている。 こうすることで、例えば CircleCI や Travis CI に変えたくなったら簡単に変えられる状態を目指している。 このため、GitHub Marketplace にある Action は使用していない。

# Makefile
deploy:
	yarn
	yarn build
	@make convert-netlify-redirect-to-firebase
	./node_modules/.bin/firebase deploy
	@make clean

clean:
	git restore firebase.json --source HEAD
	test ! -f firebase.json.tmp || rm firebase.json.tmp

convert-netlify-redirect-to-firebase:
	grep -v -e '^#' -e '^http' public/_redirects \
	  | jq -nR '{hosting: {redirects: [inputs | select(length>0)] | map(split("  ")) | map({"source": .[0], "destination": .[1], "type": .[2]})}}' \
	  | jq -s '.[0] * .[1]' firebase.json - \
	  > firebase.json.tmp
	rm firebase.json
	mv firebase.json.tmp firebase.json
# .github/workflows/firebase-deploy.yml
name: Deploy to Firebase
on:
  push:
    branches:
      - master

jobs:
  firebase-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master

      - uses: actions/cache@v2
        with:
          path: |
            **/node_modules
          key: ${{ hashFiles('**/yarn.lock') }}

      - run: make deploy
        env:
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}

所感

  • レイテンシも低くなったので良かった。
  • Firebase をもう少し使い倒したい。
  • Firebase のカスタム ドメインの反映が微妙に遅くて困った。


Author: @wk