原文:wasp-lang/open-saas · 2026-07-17
用 Open SaaS 做出并上线第一个 SaaS
这套成品已经带有落地页、注册登录、订阅支付、用户后台、管理员后台、数据分析、文件上传和演示 AI 功能。下面从空电脑开始,先把原版跑通,再改成自己的产品。

1. 准备环境
| 环境 | 要求 |
|---|---|
| Node.js | 22.12 或更高版本 |
| Docker | 本地启动 PostgreSQL 时使用,启动项目前先打开 Docker |
| macOS / Linux | 可直接安装 Wasp CLI |
| Windows | 先安装 WSL2,推荐 Ubuntu;项目必须放在 WSL 的 Linux 文件系统中 |
先检查版本:
bash
node -v
npm -v
docker --versionmacOS 或 Linux 安装 Wasp:
bash
npm i -g @wasp.sh/wasp-cli
wasp versionWindows 请在 WSL2 的 Ubuntu 终端里执行同样的命令。Apple Silicon 如果安装过程提示需要 Rosetta,再执行:
bash
softwareupdate --install-rosetta2. 创建项目
在准备存放项目的目录运行:
bash
wasp newWasp 会让你选择模板。选择 [3] saas,再输入项目名,例如 my-saas。创建完成后进入应用目录:
bash
cd my-saas/app项目根目录有三个主要部分:
| 目录 | 用途 |
|---|---|
app/ | SaaS 主应用,包含前端、后端和数据库定义 |
blog/ | 可选的 Astro 博客与文档站 |
e2e-tests/ | 端到端测试 |
3. 启动数据库和应用
打开 Docker,然后在第一个终端启动数据库:
bash
wasp start db保持它运行。打开第二个终端,仍在 my-saas/app 目录,创建数据库表:
bash
wasp db migrate-dev把示例环境变量复制为本地配置:
bash
cp .env.server.example .env.server首次只验证应用能否启动时,可以保留示例占位值;支付、真实邮件、社交登录、AI 和文件上传要等到填入对应服务的真实配置后才能使用。现在启动应用:
bash
wasp start终端完成编译后打开 http://localhost:3000。本地默认使用这些端口:
| 服务 | 地址 |
|---|---|
| Web 客户端 | http://localhost:3000 |
| API 服务 | http://localhost:3001 |
| PostgreSQL | localhost:5432 |
4. 完成第一次注册
- 在首页进入注册页,使用邮箱和密码创建账号。
- 开发环境默认使用 Dummy 邮件发送器,不会真的发邮件。
- 回到运行
wasp start的终端,找到验证邮件正文和验证链接。 - 在浏览器打开该链接,完成邮箱验证后登录。
需要直接检查数据时,在另一个终端运行:
bash
wasp db studio这会打开数据库管理界面。关闭它不会影响已运行的应用。
5. 认识已经做好的功能
注册、登录和邮件
模板已经接好邮箱注册、邮箱验证、密码重置,以及 Google、GitHub、Discord 社交登录的入口。开发阶段的 Dummy 邮件用于看完整流程;上线前再切换到真实邮件服务。

订阅和一次性付款
模板同时提供 Stripe、Lemon Squeezy 和 Polar 的实现,但一次只启用一个。默认在 src/payment/paymentProcessor.ts 选择 Stripe。付款流程已经包含:
- 登录用户选择套餐。
- 服务端创建结账会话。
- 用户前往支付服务商完成付款。
- 支付服务商调用
/payments-webhook。 - 应用根据 webhook 更新用户的订阅或点数。

管理员后台和统计
管理员登录后打开 /admin,可以看到收入、页面访问量、用户数和付费用户数。只有 isAdmin 为真的账号能进入。
本地最直接的设置方法,是在注册前把邮箱写入 .env.server:
dotenv
ADMIN_EMAILS=[email protected]也可以在 wasp db studio 中修改已经注册的用户。

文件上传
模板包含文件上传页面、服务端校验和 S3 存储实现。真正上传前,需要在 .env.server 配置 S3 访问密钥、桶名和地区。

6. 找到要改的文件
主应用按功能拆在 app/src/:
| 位置 | 改什么 |
|---|---|
main.wasp.ts | 应用名、页面、路由、登录、数据库和启用的功能 |
src/landing-page/LandingPage.tsx | 落地页结构 |
src/landing-page/contentSections.tsx | 首页文案与内容区块 |
src/landing-page/components/SchemaMarkup.tsx | 搜索引擎使用的结构化信息 |
src/auth/ | 注册、登录、验证邮件和社交登录 |
src/payment/ | 套餐、支付服务商、结账和 webhook |
src/admin/ | 管理员后台 |
src/analytics/ | 访问量、用户和收入统计 |
src/file-upload/ | 文件上传和 S3 |
src/demo-ai-app/ | 演示 AI 功能 |
7. 改成自己的产品
按这个顺序改,改完一项就刷新本地页面确认:
- 在
main.wasp.ts修改应用name和网页title。 - 替换
public/favicon.ico和public/public-banner.webp。 - 在
src/landing-page/contentSections.tsx修改产品定位、功能、案例和常见问题。 - 在
src/landing-page/components/SchemaMarkup.tsx修改产品名、网址和描述。 - 在
src/payment/paymentProcessorPlans.ts设置套餐与服务商的商品 ID。 - 在
src/payment/paymentProcessor.ts只保留 Stripe、Lemon Squeezy 或 Polar 中实际使用的一个。 - 在
main.wasp.ts的spec中移除不需要的演示 AI、文件上传、统计等功能。 - 每次数据结构发生变化后运行
wasp db migrate-dev。
8. 上线前配置
不要把 .env.server 提交到 Git。生产环境至少需要数据库、登录密钥、客户端网址和服务端网址;使用哪些功能,再补哪些变量。
| 功能 | 生产环境要完成的事 |
|---|---|
| 基础应用 | DATABASE_URL、JWT_SECRET、WASP_WEB_CLIENT_URL、WASP_SERVER_URL |
| Google 登录 | 配置正式域名的回调地址,并设置 Client ID 和 Secret |
| 真实邮件 | 设置 SendGrid Key 和发件人信息 |
| Stripe | 正式 Key、商品 ID、/payments-webhook 和 webhook secret |
| Lemon Squeezy | 正式商店、商品、webhook 和 secret |
| Polar | 正式组织和商品,将 POLAR_SANDBOX_MODE 设为 false |
| 文件上传 | S3 凭据、桶、地区,以及正式域名的 CORS |
| 数据分析 | 按所选服务填写 Plausible 或 Google Analytics 配置 |
无论选择哪个支付服务商,生产 webhook 地址都是:
text
https://你的服务端域名/payments-webhook9. 部署到 Fly.io
准备 Fly.io 账号、付款方式和 Fly CLI。Wasp 会分别创建客户端、服务端和数据库三个应用,因此应用名必须在 Fly.io 全局唯一。
在 app/ 目录执行首次部署,把名称和地区替换成自己的:
bash
wasp deploy fly launch my-saas-app dfw不要在执行过程中关闭终端。Wasp 会自动连接客户端、服务端和数据库,并设置 DATABASE_URL、JWT_SECRET、WASP_WEB_CLIENT_URL、WASP_SERVER_URL。支付、邮件、社交登录等额外密钥仍要单独设置。
首次部署会生成 fly-client.toml 和 fly-server.toml,把它们提交到自己的代码仓库。以后更新线上版本执行:
bash
wasp deploy fly deploy部署完成后逐项验收:打开首页、注册并验证邮箱、登录、打开定价页、完成支付测试、确认 webhook 更新用户状态、进入 /admin 查看数据。全部通过后,再把支付服务商从测试模式切到正式模式。