免费网站部署方案详解
静态托管、Serverless 函数、对象存储、托管数据库、免费 VPS 各自是干什么的、怎么用、能干什么不能干什么,附 2026-08-13 逐家核过的免费额度对照。
2026-08-13 整理。所有额度数字当天核过各家官方文档或定价页,个别没核到的已单独标注。 免费额度这一两年改得很勤(Netlify 换了计费模型、Koyeb 砍了免费计算),落地前建议再确认一次。
零、先搞清楚:一个网站被拆成了哪几块
这一节是理解后面所有内容的前提。「为什么会有这么多免费额度」的答案,就藏在这个拆分里。
传统做法是一台服务器包圆:nginx 发网页、PHP/Node 跑逻辑、MySQL 存数据、本地磁盘放图片。这台机器没人访问时也在开着,所以必须按月付钱。
现在的做法是把这四件事拆成四种独立的服务,每种都能按实际用量计费,闲置时用量为零:
| 网站需要的能力 | 传统做法 | 拆开之后 | 没人访问时的成本 |
|---|---|---|---|
| 发送 HTML/CSS/JS | nginx 常驻 | 静态托管 + CDN | 0(文件躺在那儿) |
| 跑动态逻辑 | PHP-FPM / Node 进程常驻 | Serverless 函数 | 0(没请求就不启动) |
| 存图片、视频、附件 | 服务器本地磁盘 | 对象存储 | 只按存了多少 GB 算 |
| 存结构化数据 | MySQL 常驻 | 托管数据库 / 边缘数据库 | 按读写次数算 |
拆开之后,一个日均几百 UV 的个人站,四块的用量都远低于各家的免费门槛——免费额度不是厂商发善心,是因为你确实几乎没消耗资源。
反过来说,这也决定了免费方案的边界:只要有一块是「必须常驻」的,免费就很难成立。想跑 WebSocket 长连接、想跑定时轮询、想跑一个内存里攒状态的进程,就得回到第六节的免费 VPS 上去。
一、静态托管(Static Hosting)
作用
把一堆已经生成好的文件(.html / .css / .js / 图片)放到全球 CDN 节点上,用户访问时从最近的节点直接返回。
关键词是「已经生成好」:服务端不做任何计算,只是把文件原样发出去。所以它天然快、天然便宜、天然扛得住流量高峰——因为发一个文件和发一百万次同一个文件,对服务器是同一件事。
使用方式
现在主流的都是 Git 驱动,流程完全一样:
1、把项目推到 GitHub / GitLab
2、在平台上「New Project」→ 选中这个仓库
3、填两个东西:构建命令(比如 npm run build)和产物目录(比如 dist)
4、以后每次 git push,平台自动拉代码、跑构建、把产物推到 CDN
# 典型配置(Astro / Vite / Next 静态导出)
Build command: npm run build
Output directory: dist不想用 Git 的话,各家也都有命令行直传:
npx wrangler pages deploy ./dist # Cloudflare Pages
npx vercel --prod # Vercel
npx netlify deploy --prod --dir=dist # Netlify
npx surge ./dist mysite.surge.sh # Surge,最简单的一种绑自定义域名就是加一条 CNAME 记录,证书各家都自动签发和续期,这块不用操心。
适合什么 / 不适合什么
| 适合 | 不适合 |
|---|---|
| 博客、文档站、作品集、落地页 | 用户登录后看到不同内容的页面 |
| 静态生成器的产物(Astro / Hugo / VitePress) | 需要写数据库的表单、后台 |
| 单页应用(SPA)的前端壳 | 需要按人做权限的私密内容 |
注意「不适合」那一列并不是死路——把动态那部分交给第二节的 Serverless 函数就行,这正是现在的标准打法。
各家对比(已核)
| 平台 | 免费额度 | 备注 |
|---|---|---|
| Cloudflare Pages | 流量不计费(官方限制表里根本没有流量这一项)、500 次构建/月、单站 2 万个文件、单文件 25 MiB、100 个自定义域、100 个项目 | 静态站首选 |
| GitHub Pages | 仓库建议 1 GB、站点上限 1 GB、软限 100 GB/月流量、软限 10 次构建/时、单次部署 ≤10 分钟 | 用自建 Actions workflow 发布则不受构建次数限制;「软限」是超了先发信提醒,不是直接断 |
| GitLab Pages | 站点 1 GB、仓库 10 GB、150 个自定义域 | Pages 请求限流 1000 次/50 秒/IP |
| Vercel Hobby | 100 万 Edge 请求、100 万函数调用、4 CPU-小时、360 GB-小时内存、5000 次图片转换、200 个项目、100 次部署/天 | 明文禁止商业用途 |
| Netlify Free | 300 credits/月 | 见下方警告 |
| Surge / Codeberg Pages / Neocities | 量都不大,胜在无商用限制、无需构建 | 额度未逐一核实 |
两条必须知道的红线
Netlify 免费版已经大幅缩水。 2025-09-04 起新账号走信用点制,300 credits/月的消耗速率是:带宽 20 credits/GB、每次生产部署 15 credits、计算 10 credits/GB-小时、Web 请求 2 credits/万次。折算下来大约是 15 GB 流量或者 20 次生产部署就见底。而且免费版不允许购买加油包,额度耗尽的后果是账号下所有站点直接暂停,访客看到 Site not available。跟 Cloudflare Pages 的「流量不计费」已经完全不在一个量级。
Vercel Hobby 的商用禁令是真会执行的。 个人博客没问题,但一旦挂广告、接商单、放公司页面,就属于违反 fair use,被封号是切实风险。这条比额度重要得多——额度超了只是暂停到下个月,违规是直接停用。
二、Serverless 函数(无服务器函数 / 边缘函数)
这一节是重点,因为它最容易被「听起来很玄」劝退,实际上概念极简单。
作用:一句话解释
它就是一个函数,收一个 HTTP 请求,返回一个 HTTP 响应。有人访问才启动,跑完就销毁。
跟传统后端唯一的区别是「谁来管进程」:
| 传统后端 | Serverless 函数 | |
|---|---|---|
| 谁启动进程 | 你自己 node server.js,然后它一直开着 | 平台在收到请求的那一刻启动 |
| 没请求的时候 | 进程还在,内存还占着,钱照付 | 什么都没有,不花钱 |
| 流量突然涨十倍 | 你得自己加机器 | 平台自动跑一百个实例 |
| 你要写的代码 | 监听端口、路由、启动、优雅退出 | 只写那个处理函数 |
「Serverless」不是「没有服务器」,是「服务器不归你管」。
使用方式:三家的最小例子
Cloudflare Workers —— 一个文件就是一个服务:
// src/index.js
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
if (url.pathname === '/api/time') {
return Response.json({ now: Date.now() });
}
return new Response('Hello', { status: 200 });
}
};npm create cloudflare@latest # 建项目
npx wrangler dev # 本地跑,localhost:8787
npx wrangler deploy # 部署,秒级生效Vercel Functions —— 文件路径就是 URL 路径:
// api/hello.js → 自动对应 https://你的站/api/hello
export function GET(request) {
const name = new URL(request.url).searchParams.get('name') ?? 'world';
return Response.json({ hello: name });
}Deno Deploy —— 更直白:
Deno.serve((req) => new Response('Hello from the edge'));三家的心智模型是同一个:导出一个函数,入参是 Request,返回值是 Response。 这是 Web 标准的 Fetch API,浏览器里那个 fetch 的另一半。
怎么调用它
它就是一个普通的 URL,没有任何特殊之处。 前端这样调:
const res = await fetch('/api/time');
const data = await res.json();也可以直接浏览器地址栏打开、可以 curl、可以给别的服务当 Webhook 回调地址。没有 SDK,没有客户端库,就是 HTTP。
十种典型用途
1、藏 API 密钥。前端直接调第三方 API 会把密钥暴露在浏览器里。让函数当中转,密钥只存在服务端的环境变量里:
export default {
async fetch(request, env) {
// env.API_KEY 来自平台的环境变量配置,前端永远看不到
return fetch('https://api.example.com/v1/chat', {
method: 'POST',
headers: { Authorization: `Bearer ${env.API_KEY}` },
body: request.body,
});
}
};2、接收表单提交。静态站最缺的一块。函数收到 POST,转发到邮箱 / 数据库 / 飞书机器人。
3、接收 Webhook。GitHub push、支付回调、Stripe 事件、Telegram Bot——这些第三方服务需要一个「随时能被叫醒」的 URL,函数正是为此而生。
4、API 反向代理 / 加速。国内访问不了的 API,套一层 Workers 就通了;也能顺手改请求头、加缓存、做限流。
5、动态生成图片。访问 /og?title=xxx 实时渲染一张社交分享卡片,不用给每篇文章预先生成。
6、做鉴权门禁。函数验一下 Cookie / JWT,通过才回源取内容,否则跳登录。静态站加会员区就靠这个。
7、A/B 测试和灰度。边缘函数在请求到达 CDN 那一刻就能改写路由,把 10% 的人导到新版本。
8、地理位置定制。边缘节点知道访客在哪个国家,可以自动切语言、切货币、切区域合规提示。
9、访问统计。自己攒一个轻量计数器写进 KV,不用引入第三方分析脚本。
10、定时任务。Cloudflare 的 Cron Triggers、Vercel 的 Cron Jobs,用 cron 表达式定时唤醒函数,做签到、抓取、日报。
它干不了什么(重要)
| 干不了 | 原因 | 替代方案 |
|---|---|---|
| 跑几分钟的重任务 | 有执行时长上限(Workers 免费版每次 10 ms CPU 时间,Vercel 最长 300 秒) | 拆成队列 + 多次调用,或上真机器 |
| 在内存里攒状态 | 每次请求可能是全新实例,上次的变量没了 | 状态写进 KV / 数据库 |
| 写本地文件 | 文件系统是临时的,实例销毁即丢 | 写对象存储 |
| 维持 WebSocket 长连接 | 与「跑完就销毁」的模型冲突 | Cloudflare Durable Objects,或第六节的常驻机器 |
| CPU 密集计算(转码、训练) | CPU 时间额度极小 | 本地跑完传上去 |
注意 Workers 免费版 10 ms CPU 时间这个限制经常被误读:它算的是实际占用 CPU 的时间,不包括等待外部 API 返回的时间。所以「调个 API 再返回」完全没问题,「循环算十万次哈希」才会超。
冷启动
函数闲置一段时间后,下一个请求需要先把运行时拉起来,这段额外延迟叫冷启动。
Cloudflare Workers 用的是 V8 isolate 而不是容器,冷启动基本感知不到(官方限制是 1 秒内启动)。Vercel / AWS Lambda 的 Node 运行时会明显一些,通常几百毫秒。个人站这个量级不用在意。
各家额度(已核)
| 平台 | 免费额度 |
|---|---|
| Cloudflare Workers | 10 万请求/天(≈300 万/月)、每次调用 10 ms CPU、出站流量免费、Worker 压缩后 ≤3 MB、每请求最多 50 个子请求 |
| Deno Deploy | 100 万请求/月、20 GB 出站、15 小时 CPU、350 GB-小时内存、20 个活跃部署、50 个自定义域 |
| Vercel Functions | 含在 Hobby 里:100 万次调用 + 4 CPU-小时 + 360 GB-小时内存,单次最长 300 秒 |
| Google Cloud Run | 有永久免费额度(约 200 万请求 + 40 万 vCPU-秒/月),这组数字没从官方页核到,用前自行确认 |
| Netlify Functions | 不单列,走那 300 credits |
三、对象存储(Object Storage)
作用
一个只按 GB 收钱的网盘,但有 HTTP 接口,可以直接当图床/文件服务器用。
它和你熟悉的「硬盘目录」有三个本质区别,理解了这三点就理解了它的全部:
1、没有真正的文件夹。photos/2026/a.jpg 整个是一个 key(名字),斜杠只是名字里的字符。所以「重命名文件夹」这种操作不存在,得逐个改 key。
2、不能改一小段。要修改文件只能整个重新上传(覆盖),没有「在第 300 字节处写 4 个字节」这种操作。
3、天生带 URL。每个对象都能有一个公网地址,配上 CDN 直接就是图床。
使用方式:三种姿势
姿势一:控制台手动拖拽。 建桶 → 拖文件进去 → 复制链接。适合偶尔传几张图。
姿势二:S3 API / rclone 批量同步。 几乎所有对象存储都兼容 AWS S3 的接口协议(R2、MinIO、B2 都兼容),所以工具是通用的:
# rclone:本地目录 → 桶,增量对账,本地删了桶里也跟着删
rclone sync ./public/video r2:my-bucket/video --progress
# 也能反过来,或者在两家云之间直接倒
rclone sync r2:bucket-a b2:bucket-b代码里则用官方 SDK:
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
const s3 = new S3Client({
region: 'auto',
endpoint: 'https://<账号ID>.r2.cloudflarestorage.com', // R2 就是改这一行
credentials: { accessKeyId: KEY, secretAccessKey: SECRET },
});
await s3.send(new PutObjectCommand({
Bucket: 'my-bucket', Key: 'photos/a.jpg', Body: buffer,
ContentType: 'image/jpeg',
}));姿势三:预签名 URL(Presigned URL)——用户直传。
这是对象存储最有价值的用法之一。用户要上传一个 500 MB 的视频,如果先传到你的服务器再转存,你要承担双倍流量和带宽。预签名 URL 的做法是:
1、前端问你的函数:「我要传个文件」
2、函数用密钥签一个有时限的临时上传地址(比如 15 分钟内有效)返回给前端
3、前端拿这个地址直接把文件 PUT 到对象存储,完全不经过你的服务器
密钥始终没有离开服务端,而流量成本被完全绕开了。
典型用途
图床和视频托管、用户上传的附件、网站备份和数据库快照、大文件分发(安装包、数据集)、静态站的原始素材仓库。还有一个近年流行的新玩法:把 SQLite 数据库文件本身放进对象存储,靠条件写入实现一个没有常驻数据库的后端(ServerlessWP 就是这么干的)。
「出站流量免费」为什么是决定性的
对象存储的账单有三项:存了多少(storage)、操作了多少次(operations)、传出去多少流量(egress)。
前两项在个人使用量级下都是零头,真正会把账单炸掉的永远是第三项。AWS S3 的出站流量约 $0.09/GB,一个稍微火一点的视频页就能跑出三位数账单——这是无数人踩过的坑。
Cloudflare R2 的出站流量是 0 元,不设上限。 这一条让它在图床、视频、大文件分发这三个场景里没有对手,10 GB 的免费存储反而是次要的。
各家额度(已核)
| 平台 | 免费额度 |
|---|---|
| Cloudflare R2 | 10 GB-月存储、100 万次 Class A 操作(写类)、1000 万次 Class B 操作(读类),出站流量完全免费。仅限标准存储层 |
| Firebase Storage | 新版桶 5 GB-月 + 100 GB/月下载(仅美区);老的 appspot.com 桶只有 5 GB + 1 GB/天 |
| Supabase Storage | 1 GB 文件 + 5 GB 出站 |
| Oracle 对象存储 | 20 GB + 5 万次 API 请求/月 |
四、KV / 缓存
作用
一个全球分布的巨型 Map,put(key, value) / get(key),值可以是字符串或二进制。
它的定位介于「数据库」和「变量」之间:比数据库简单得多(没有表、没有 JOIN、没有查询语言),但比内存变量持久(函数实例销毁了数据还在,而且全球节点都能读到)。
使用方式
export default {
async fetch(request, env) {
// 读
let html = await env.MY_KV.get('homepage');
if (!html) {
html = await renderHomepage();
// 写,带 1 小时过期
await env.MY_KV.put('homepage', html, { expirationTtl: 3600 });
}
return new Response(html, { headers: { 'content-type': 'text/html' } });
}
};用途
缓存渲染结果、存会话(session)、存功能开关和配置、做计数器和限流、存短链映射。
有个关键特性必须知道:KV 是最终一致的(eventually consistent)。写入后各地节点同步需要时间(通常几十秒内),所以不要用它存「必须立刻读到最新值」的东西,比如库存、余额、验证码。那些该用数据库。
Cloudflare Workers KV 免费额度:10 万次读/天、1000 次写/天、1000 次删/天、1 GB 存储。注意读写额度差了一百倍——它的设计假设就是「读多写极少」,别拿它当数据库用。
五、托管数据库
三种形态,别搞混
| 形态 | 代表 | 特点 | 什么时候用 |
|---|---|---|---|
| 边缘 SQL | Cloudflare D1(SQLite) | 跟函数同一个平台,延迟极低,按行读写计费 | 数据量小、读多写少、已经在用 Workers |
| 托管 Postgres | Supabase、Neon、TiDB | 完整的关系型数据库,能跑复杂 SQL、事务、外键 | 正经应用,需要关系和事务 |
| 文档数据库 | Firebase Firestore | 存 JSON 文档,前端可直连,自带实时订阅 | 需要实时同步的场景(聊天、协作) |
怎么调用
D1(绑定到 Worker 后直接可用,不用连接字符串):
const { results } = await env.DB
.prepare('SELECT * FROM posts WHERE author = ?')
.bind(authorId)
.all();Supabase(有 JS SDK,也能直接用 Postgres 连接串):
const { data, error } = await supabase
.from('posts')
.select('id, title')
.eq('author', authorId);Supabase 额外送一整套东西:认证(邮箱/OAuth 登录)、行级权限(RLS)、自动生成的 REST 和 GraphQL 接口、实时订阅、文件存储。它是这里面唯一一个「开箱即用的完整后端」,如果要做带登录的应用,它省的事最多。
各家额度和失效方式(已核)
「失效方式」这一列比额度本身重要——免费数据库超限时不是降速,而是直接不可用:
| 平台 | 免费额度 | 超限/到期时会怎样 |
|---|---|---|
| Cloudflare D1 | 500 万行读/天、10 万行写/天、总计 5 GB | 超额后 API 直接报错,UTC 00:00 重置 |
| Supabase | 500 MB 库、5 GB 出站、1 GB 文件、5 万 MAU、50 万边缘函数调用、2 个活跃项目 | 闲置 1 周自动暂停项目 |
| Firebase Firestore | 1 GiB 存储、每天 5 万读 / 2 万写 / 2 万删、10 GiB/月出站 | 超额停止服务至次日 |
| Render Postgres | 1 GB,每工作区 1 个 | 建库 30 天后过期,再给 14 天宽限期就删库 |
| TiDB Serverless | 免费层比较大方,具体数字未核 | |
| Koyeb Postgres | 5 小时/月 | 等于没有 |
Render 那条要特别留意:它不是「用超了停」,是「时间到了就删」,从设计上就不适合放任何你在乎的数据。
六、能跑 24/7 的免费机器
前面五节都是「拆开来按量付费」的思路。但有些东西天生需要一台常驻的机器:WebSocket 服务、定时轮询、自建 Docker 服务、跑长任务、要装数据库和 Redis。这时候就得要真机器。
| 平台 | 免费额度(已核) | 说明 |
|---|---|---|
| Oracle Cloud Always Free | 2 台 AMD E2.1.Micro(1/8 OCPU + 1 GB)外加 ARM Ampere A1 共 1500 OCPU-时 + 9000 GB-时/月(够常开 2 OCPU + 12 GB)、200 GB 块存储、10 TB/月出站、1 个负载均衡器(10 Mbps)、20 GB 对象存储 | 免费方案里的天花板 |
| Render Web Service | 750 实例小时/月 | 15 分钟无请求就休眠,唤醒约 1 分钟;文件系统临时,重新部署即丢 |
| Koyeb | 已取消免费计算,最低 Pro $29/月 |
Oracle 的 ARM 那一份是真的强:2 核 12 G 常开 + 10 TB 出站,量级上直接对标一台付费 VPS。它能装 Docker、能跑 Nginx + MySQL + Redis 全家桶、能自建任何东西。
代价是甲骨文以两件事出名:开户风控严(不少人卡在验证或被莫名封号)、会回收长期闲置的免费实例。所以定位应该是「白嫖一台干活的机器」,而不是「放唯一一份数据的地方」——重要数据务必另做备份。
Fly.io 和 Railway 据说也砍了免费层,但这次没核,不下结论。
七、把它们拼起来:五种典型组合
| 场景 | 组合 | 说明 |
|---|---|---|
| 纯静态博客 | Cloudflare Pages | 一块就够了。流量不计费,构建 500 次/月对个人站是天文数字 |
| 博客 + 评论/统计 | Cloudflare Pages + Workers + D1 | 评论走函数写 D1,全在一家,绑定即用不用连接串 |
| 图床 / 视频站 | Cloudflare Pages + R2 | 决定性因素是 R2 出站免费。大文件走预签名 URL 直传 |
| 带登录的小应用 | Cloudflare Pages(前端)+ Supabase(认证 + 库 + 存储) | Supabase 把登录、权限、API 全包了,省掉大半后端 |
| 需要常驻进程 | Oracle Always Free + Docker | WebSocket、定时任务、自建服务;前面几种都做不到这个 |
一个通用建议:能整套上 Cloudflare 就整套上。 它是唯一一家把「出站流量」从计费模型里彻底拿掉的,别家的免费额度迟早卡在带宽这一项上。同一家内部的服务还能直接绑定调用(Worker 里 env.DB、env.MY_KV、env.MY_BUCKET),不用管连接串和密钥。
它的短板只有一个:Workers 免费版每次调用 10 ms CPU 时间,重计算跑不动。真需要算东西再往别处挪。
八、九条避坑清单
1、Vercel Hobby 禁止商业用途。挂广告、接单、公司站都算违规,风险高于额度超限。
2、Netlify 免费版已缩水到 300 credits/月(约 15 GB 流量或 20 次部署),耗尽后全站暂停且不能补购。
3、免费数据库都别当唯一副本。Supabase 闲置一周暂停、Render 三十天删库、D1 超额当天报错——三种都是「不可用」而不是「变慢」。
4、盯住出站流量,别盯存储容量。真正炸账单的永远是 egress。S3 约 $0.09/GB,R2 是 0。
5、Workers KV 每天只有 1000 次写。它是读多写少的缓存,不是数据库。
6、KV 是最终一致的,别拿它存库存、余额、验证码这类必须立刻读到最新值的东西。
7、函数里不要写本地文件、不要在内存里攒状态,实例随时会被销毁。
8、Oracle 会回收闲置实例,别把唯一一份数据放上面。
9、免费额度会变。这份笔记的数字是 2026-08-13 核的,半年后大概率要重核一遍——Netlify 从「100 GB 流量」变成「15 GB 等效」只用了不到一年。
评论
评论加载中……