Firebase Hosting 是静态 Astro 站的稳健便宜选项。部署本身很短,麻烦都在配置里。
问题背景
Firebase Hosting 提供免费 SSL、全球 CDN、可预测计费。Astro 输出到 dist/,Firebase 直接 serve。主要摩擦在 firebase.json 的 rewrites、缓存头,以及 Firebase 如何解析 /articles/slug/ 这种干净 URL。
判断标准
- 想要可预测计费和能覆盖小站的免费额度。
- 已经在用其他 Firebase 服务,想统一平台。
- 不需要 SSR,静态输出就够。
- 能接受 CLI 部署步骤。
快速结论
看重计费可预测和 Firebase 生态匹配,选 Firebase;看重 DX 和零配置,选 Vercel。
实操步骤
- 全局装 Firebase CLI 并登录:
npm install -g firebase-tools
firebase login
- 在 Astro 项目根目录初始化 hosting。public 目录填
dist;“配置成 SPA(所有 URL rewrite 到 /index.html)“——选 No。Astro 输出的是真路由,不是 SPA shell:
firebase init hosting
# ? What do you want to use as your public directory? dist
# ? Configure as a single-page app (rewrite all urls to /index.html)? No
# ? Set up automatic builds and deploys with GitHub? (自己选)
- 改
firebase.json处理干净 URL、缓存头和真正的 404。下面这份配置规避了几乎所有常见坑:
{
"hosting": {
"public": "dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"cleanUrls": true,
"trailingSlash": true,
"headers": [
{
"source": "/_astro/**",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
]
},
{
"source": "**/*.@(jpg|jpeg|png|webp|avif|svg|woff2)",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=2592000" }
]
},
{
"source": "**/*.html",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=300, s-maxage=3600" }
]
}
]
}
}
astro.config.mjs里site:一定要配,sitemap 和 canonical 都依赖它:
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';
export default defineConfig({
site: 'https://yourdomain.com',
trailingSlash: 'always',
build: { format: 'directory' },
integrations: [sitemap()],
});
- 构建后部署:
npm run build
firebase deploy --only hosting
# Hosting URL: https://your-project.web.app
-
Firebase Console → Hosting → Add custom domain,按提示配 DNS(一般是两条指向 Firebase IP 的 A 记录)。DNS 生效后 SSL 自动签发,通常 1-24 小时。
-
上线后用
curl -I验证缓存头:
curl -sI https://yourdomain.com/ | grep -i cache-control
# cache-control: public, max-age=300, s-maxage=3600
curl -sI https://yourdomain.com/_astro/index.abc123.css | grep -i cache-control
# cache-control: public, max-age=31536000, immutable
- 故意访问一个不存在的 URL(
/this-does-not-exist/),确认返回 404,不是 200 + 渲染首页。如果是 200,说明 rewrites 还在按 SPA 方式生效。
容易踩的坑
- 接受默认 SPA rewrite——404 页面返回 200,Google 会困惑。你想要的 rewrite 却悄悄没生效时,多半是规则顺序、或者被同路径静态文件挡住(rewrite 没触发)。
- 忘配缓存头,默认值保守,回访速度慢。
- SSL 还没签发就把 DNS 切过去,访问者看到警告直到全网生效。
- 想在 Firebase Hosting 上跑 SSR Astro 却没用 Cloud Functions——只能 serve 静态。即使接好了函数,返回「function not found」一般是区域或函数名对不上,不是部署失败(Firebase function not found)。
astro.config.mjs漏配site:,sitemap 就废了。
这篇适合谁
在 Firebase 生态里的独立开发者,或者想要可预测计费的人。
这篇不适合谁
需要 SSR 重度场景的,考虑 Vercel 或 Cloudflare Pages 等带服务端运行时的方案。
FAQ
- Firebase Hosting 真的免费吗: 免费额度宽松(1 GB 存储、10 GB/月流量)。超出 Blaze 计费很便宜,对静态站几乎无感。
- 怎么在 Firebase 跑 Astro SSR: 后端用 Cloud Functions 或 Cloud Run + Astro Node adapter。大部分内容站用不上。
- 能从 GitHub 自动部署吗: 可以——
firebase init hosting:github自动建 GitHub Action。比手动部署省心。 - 部署翻车怎么回滚: Firebase Hosting 保留部署历史,用
firebase hosting:clone或在 Console 回滚都很快。