👾

静的なサイトをGoogle App EngineからFirebase Hostingにお引っ越しして独自ドメイン当てた記録

2022/07/02に公開

今回やること

Google App Engineで動かしていた自サイトの一部コンテンツをFirebase Hostingにお引越する。

具体的には
https://xiidec.appspot.com
の一部コンテンツである
https://xiidec.appspot.com/colamone/colamone.html

https://colamone.com
に移動したい。

その過程で独自ドメインも当てる。

お引越しが終わったら旧サイトから新サイトへ301リダイレクトする。

今回移行するのはこういうページ。全部フロント側で処理をするボードゲーム。バックエンドの処理はない。

Firebaseへの移行

まずはGoogle App Engineからfirebase Hostingへ移行する。
GAEもFirebase Hostingもどっちも無料で使えるし、どっちも高速なCDNに乗るのであまり移行にメリットはない。でもGAEを静的ファイル置き場にするのもなんか違うなと思って移行することにした。

firebase CLIをインストール

ここからダウンロードしてもいいけれど、今回はnpm経由で入れた。なんかそっちの方が後々便利そうな予感がする。

npm install -g firebase-tools

インストールできたらさっそくログイン。

firebase login

そしてさっそくエラー。Windowsは外部から取得したスクリプトに厳しい。

firebase : このシステムではスクリプトの実行が無効になっているため、ファイル C:\Program Files\nodejs\firebase.ps1 を読み
込むことができません。詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参
照してください。
発生場所 行:1 文字:1
+ firebase login
+ ~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

Windows向けfirebase-toolsはPowerShellで実装されているらしい。
Windowsの初期設定(Restricted)ではPowerShellはすべてのスクリプトの実行が禁止されている。
「UnauthorizedAccess firebase」でググると「Bypassに設定すると動くよ」という情報が見つかる。でもノーガード戦法はセキュリティ的にあまり良くないので、今回は「RemoteSigned」に設定しておく。これで十分動く。

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

firebaseプロジェクトを作る

作る。

リポジトリをfirebaseと接続する

接続したいリポジトリのディレクトリに移動して実行。

firebase init

すると質問攻めにあう。

? Are you ready to proceed? Yes

準備できているか、という確認。Yesと答える。

? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confir
m your choices. Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys

firebase hostingを使いたいのでfirebase hostingを選択。
次にプロジェクトを新規作成するか既にあるものかを聞かれた。
Web上で既にプロジェクトを作成済みだったのでExistingを選択。

? What do you want to use as your public directory? docs

公開ディレクトリをどこにするかを聞かれた。
Reactなら「public」を選択するんだろうけど、Github Pages向けにdocsフォルダを公開ディレクトリにしていたので今回は「docs」と入力。

? Configure as a single-page app (rewrite all urls to /index.html)? No

すべてのアクセスをindex.htmlにリダイレクトするらしい。やめてほしい。No。

? Set up automatic builds and deploys with GitHub? Yes

  • Wrote docs/404.html

GitHubで自動ビルドとデプロイを設定するかどうか。やってほしい。Yes。

? File docs/index.html already exists. Overwrite? No
i Skipping write of docs/index.html

既にあるdocs/index.htmlを上書きするかどうか。なぜそんなことするのか。やめてほしい。

Visit this URL on this device to log in:

Githubへの認可を求められる。

? For which GitHub repository would you like to set up a GitHub workflow? (format: user/repository) kurehajime/colamone_
js

Githubのワークフローを作るリポジトリを指定。

? Set up the workflow to run a build script before every deploy? Yes

デプロイ前にビルドスクリプトを実行するかどうか。して欲しい。Yes。

? What script should be run before every deploy? (npm ci && npm run build)

ビルドスクリプトのコマンドを指定。

? Set up automatic deployment to your site's live channel when a PR is merged? Yes

PRをマージした時にデプロイするかどうか。して欲しい。Yes。

? What is the name of the GitHub branch associated with your site's live channel? master

デプロイ対象のブランチ。
今の時流的にはmainが良いんだろうけど、古いリポジトリなのでmaster。

commit & push

Github Actionが追加されたので、それをCommit&Push。
するとさっそくデプロイされた。

動作確認 & チューニング

普通に動いている。



パフォーマンスも見てみる。

同じソースをGoogle App EngineでデプロイしたもののPage Speed Insightの点数(PC版)。モバイルはもっと低い。

Firebase HostingにアップロードしたバージョンのPage Speed Insightの点数。1点落ちてる。

Google App Engine版ではキャッシュで怒られるリソースが4つしかない。

Firebase Hostingでは6つのリソースで怒られる。キャッシュが1時間しか持たない。

firebase.jsonにキャッシュの設定を追加した。
アセット類をバンドラーで毎回Packし直すならもっと長くしても良い。

{
  "hosting": {
    "public": "docs",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "headers": [{
      "source": "**/*.@(jpg|jpeg|gif|png)",
      "headers": [ {
        "key": "Cache-Control",
        "value": "max-age=5184000"
      }]
    }, {
      "source": "**/*.@(js)",
      "headers": [ {
        "key": "Cache-Control",
        "value": "max-age=604800"
      }]
    },
    {
      "source": "**/*.@(css)",
      "headers": [ {
        "key": "Cache-Control",
        "value": "max-age=1209600"
      }]
    },
    {
      "source": "**/*.@(woff|woff2)",
      "headers": [ {
        "key": "Cache-Control",
        "value": "max-age=10368000"
      }]
    }]
  }
}

キャッシュが延長され無事警告が減った。キャッシュ時間をもっと伸ばせばまだ減らせる。


独自ドメインを当てる

カスタムドメインを追加をクリック

あらかじめ取得しておいたドメインを入力。muumuuドメインでとった。

「お前が本当に所有者なら、TXTレコードにこれを追加してみせろ」と煽られる。

言われたとおりに追加する。

するとIPアドレスを教えてもらえるので、こちらも追加する。

リダイレクトする

旧サイトから新サイトにリダイレクトしたい。
検索エンジンに「引っ越しました」と伝わるように301リダイレクトで。

旧サイトではapp.yamlでは静的ファイルにルーティングをしていた。

- url: /colamone/(.*\.(html))
  static_files: colamone/\1
  upload: colamone/(.*\.(html))
  expiration: "1d"
  secure: always

これをこう書き換えて、バックエンドに処理を流す。

 - url: /colamone/(.*\.(html))
  script: auto

もともとの環境はGo言語で実装していた。
そこに301リダイレクトのハンドラーを追加。

func main() {
	(中略)
	http.HandleFunc("/colamone/index.html", colamoneHandler)
}

func colamoneHandler(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r, "https://colamone.com", 301)
}

これで旧サイトにアクセスした時にリダイレクトされるようになった。

Discussion