このブログ(45395.jp)はAstroで作った静的サイトです。もともとXserverでホスティングしていましたが、Firebase Hostingに移行しました。GitHub ActionsでCI/CDを組んで、mainブランチにプッシュするだけで自動デプロイされる環境を構築しています。
本記事では、その構築手順と、実際にハマったポイントを共有します。
対象読者
- Astro製の静的サイトをFirebase Hostingに移行したいエンジニア
- GitHub Actionsで自動デプロイを組みたいひと
- Cloudflare + Firebase の組み合わせで詰まっているひと
前提条件
- Node.js >= 18
- pnpm >= 8
- Firebase CLI(
npm install -g firebase-tools) - GitHubリポジトリ
- Firebaseプロジェクト作成済み
1. Firebase Hosting のセットアップ
firebase.json を作成する
プロジェクトルートに firebase.json を配置します。Astroのビルド出力先は dist/ です。
1{2 "hosting": {3 "public": "dist",4 "ignore": ["firebase.json", "**/.*", "**/node_modules/**"]5 }6}注意: Vercel や Netlify と異なり、Firebase Hosting はビルドを自前で行いません。public にはビルド済みのディレクトリを指定します。
.firebaserc を作成する
1{2 "projects": {3 "default": "your-project-id"4 }5}プロジェクトIDはFirebaseコンソールの「プロジェクトの設定」から確認できます。
動作確認(手動デプロイ)
1pnpm build2firebase deploy --only hostingHosting URL: https://your-project-id.web.app が表示されれば成功です。
2. GitHub Actions で自動デプロイ
サービスアカウントキーの取得
- Firebase コンソール → プロジェクトの設定 → サービスアカウント タブ
- 「新しい秘密鍵の生成」をクリック → JSONファイルをダウンロード
GitHub Secrets に登録
GitHubリポジトリの Settings → Secrets and variables → Actions で追加:
| Name | Value |
|---|---|
FIREBASE_SERVICE_ACCOUNT | ダウンロードしたJSONの中身をそのままペースト |
ワークフローファイルを作成
.github/workflows/firebase-hosting-merge.yml — main ブランチへのプッシュで本番デプロイ:
1name: Deploy to Firebase Hosting on merge2on:3 push:4 branches:5 - main6jobs:7 build_and_deploy:8 runs-on: ubuntu-latest9 steps:10 - uses: actions/checkout@v411 - uses: pnpm/action-setup@v412 with:13 version: 814 - uses: actions/setup-node@v415 with:9 collapsed lines
16 node-version: 2017 cache: pnpm18 - run: pnpm install && pnpm build19 - uses: FirebaseExtended/action-hosting-deploy@v020 with:21 repoToken: ${{ secrets.GITHUB_TOKEN }}22 firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}23 channelId: live24 projectId: your-project-id.github/workflows/firebase-hosting-pull-request.yml — PRにプレビューURLを自動生成:
1name: Deploy to Firebase Hosting on PR2on: pull_request3permissions:4 checks: write5 contents: read6 pull-requests: write7jobs:8 build_and_preview:9 if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}10 runs-on: ubuntu-latest11 steps:12 - uses: actions/checkout@v413 - uses: pnpm/action-setup@v414 with:15 version: 810 collapsed lines
16 - uses: actions/setup-node@v417 with:18 node-version: 2019 cache: pnpm20 - run: pnpm install && pnpm build21 - uses: FirebaseExtended/action-hosting-deploy@v022 with:23 repoToken: ${{ secrets.GITHUB_TOKEN }}24 firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}25 projectId: your-project-idこれで main にプッシュするたびに自動デプロイされます。
3. カスタムドメインの設定
your-project-id.web.app ではなく独自ドメインで公開する手順です。
Firebase コンソールでドメインを追加
- Hosting → カスタムドメインを追加 をクリック
- ドメイン名(例:
45395.jp)を入力
DNS に TXT レコードを追加(所有権確認)
Firebaseが指示するTXTレコードをDNSプロバイダに追加します。
1タイプ: TXT2名前: 45395.jp(または @)3値: hosting-site=your-project-idDNSの反映を確認:
1dig your-domain.jp TXT +short2# "hosting-site=your-project-id" が返ってくればOKDNS に A レコードを追加
Firebaseが指示するIPアドレスにAレコードを向けます。
1タイプ: A2名前: your-domain.jp3値: 199.36.158.100(Firebaseが指定するIP)ハマりポイント集
実際に詰まった箇所を共有します。
① @astrojs/sitemap がビルドエラーになる
症状:
1Cannot read properties of undefined (reading 'reduce')2# または3destinationDir must be a relative path (absolute paths are not allowed)原因: sitemap@7.1.3(@astrojs/sitemapの内部依存)が絶対パスを拒否するバリデーションを追加した。astro@4.x系との組み合わせで発生。
対処: package.json でバージョンを固定し、pnpm overrides で内部依存も固定する。
1{2 "dependencies": {3 "@astrojs/sitemap": "3.1.1",4 "astro": "4.5.5"5 },6 "pnpm": {7 "overrides": {8 "sitemap": "7.1.1"9 }10 }11}② Cloudflare プロキシが ACME チャレンジをブロックする
症状: Firebase Hosting のカスタムドメイン設定でSSL証明書の発行が失敗する。
1ACME チャレンジで HTTP GET リクエストが失敗しました2104.21.83.100: 404 Not Found原因: CloudflareのDNSプロキシ(オレンジ雲)が有効だと、FirebaseへのACMEチャレンジリクエストをCloudflareが横取りして404を返す。
対処: CloudflareのDNSレコードをプロキシ無効(グレー雲=DNS only)に変更する。Firebase Hosting を使う場合、基本的に Cloudflare プロキシは不要です。
③ DNS は正しいのに Firebase が「レコードが検出されていません」と言い続ける
症状: TXTレコードを追加したのにFirebaseが検出できないと言う。
確認方法:
1dig your-domain.jp TXT +short2# "hosting-site=your-project-id" が返ってくるか確認対処: dig で正しく返ってきていれば、Firebase の検証サーバー側のDNSキャッシュが古いだけです。Firebase のダイアログで「確認」ボタンを数分おきに押し続けてください。最大24時間と書いてありますが、実際は数回押せば通ります。
④ ドメインが「接続済み」なのに404になる
症状: Firebaseコンソールで「接続されています」になったのに https://your-domain.jp/ が404。
原因: Firebase CDN(Fastly)が古い404レスポンスをキャッシュしている(x-cache: HIT)。
対処: 再デプロイするとキャッシュがパージされます。
1firebase deploy --only hostingまとめ
| ステップ | 所要時間の目安 |
|---|---|
| firebase.json / .firebaserc 作成 | 5分 |
| GitHub Actions ワークフロー作成 | 10分 |
| GitHub Secrets 登録 | 5分 |
| カスタムドメイン設定(DNS反映待ち含む) | 30分〜数時間 |
Firebase Hosting は無料枠(Sparkプラン)でも静的サイトのホスティングとして十分な機能があります。GitHub Actionsとの連携も公式アクションが提供されているため、設定自体は難しくありません。
ハマりポイントの多くはDNS周りとパッケージバージョンの組み合わせ問題でした。本記事の内容が同じ構成で詰まっているかたの参考になれば幸いです。