Wasp 应用云平台部署实战指南:Fly.io / Railway / Heroku / Netlify / Cloudflare 全流程解析
【免费下载链接】waspThe batteries-included full-stack framework for the AI era. Develop JS/TS web apps (React, Node.js, and Prisma) using declarative code that abstracts away complex full-stack features like auth, background jobs, RPC, email sending, end-to-end type safety, single-command deployment, and more.项目地址: https://gitcode.com/GitHub_Trending/wa/wasp
本篇指南围绕 Wasp 全栈框架的生产环境部署展开:Wasp 编译产物是标准的 Node.js 服务端 + 静态 Web 客户端 + PostgreSQL 数据库三件套,因此可以部署到任何支持这三者的云平台。文章先拆解部署的四个通用步骤与必需环境变量,再依次给出 Fly.io、Railway、Heroku、Netlify、Cloudflare 五个主流平台的分步实操命令,并补充一键部署命令wasp deploy的用法。读完你可以在任意目标平台独立完成一次 Wasp 应用的生产部署与后续更新。
部署全景:Wasp 应用上线 = 四步走
Wasp 框架把完整的前后端应用编译为标准的可部署产物。无论选哪家云厂商,一次成功的生产部署都可以归结为以下四件事(出处:deployment/deployment-methods/paas.md):
- 生成可部署代码(
wasp build); - 部署 API 服务器(后端);
- 部署 Web 客户端(前端);
- 部署并维持一个 PostgreSQL 数据库的运行。
只要你的目标平台能够运行 Node.js 服务器、托管静态文件并连接 PostgreSQL 数据库,理论上就可以托管 Wasp 应用。下文将依次展开。
第一步:用wasp build生成可部署代码
在 Wasp 项目根目录执行:
wasp build该命令会为整个应用生成可部署代码,输出到.wasp/build/目录。整个构建产物按职责拆分:
.wasp/build/根目录下有一个Dockerfile,用于构建服务器镜像;.wasp/build/web-app/是 Web 客户端源码(Vite 工程);- 对客户端执行生产构建后,静态文件会落在
.wasp/build/web-app/build/。
⚠️ 生产环境必须使用 PostgreSQL如果你当前使用 SQLite(Wasp 的默认数据库),将无法成功构建生产包。部署到生产环境前,必须先从 SQLite 迁移到 PostgreSQL。这是最容易在部署前踩的坑。
第二步:部署 API 服务器(后端)
服务器部分就是.wasp/build/下的 Dockerfile 所定义的镜像。你需要把它部署到支持容器运行的主机上,并确保服务器运行所需的环境变量全部就位——通常通过云厂商控制台或 CLI 设置。
服务器必需的环境变量清单(详见 deployment/env-vars.md 的 Server Env Vars 一节):
| 环境变量 | 类型 | 必填 | 说明 |
|---|---|---|---|
DATABASE_URL | String | 是 | 应用要连接的 PostgreSQL 数据库 URL |
WASP_WEB_CLIENT_URL | URL | 是 | 客户端 URL;服务器在发邮件、OAuth 跳转等场景用它拼接链接 |
WASP_SERVER_URL | URL | 是 | 服务器自身 URL;OAuth 登录回调等场景使用 |
JWT_SECRET | String | 是 | 至少 32 字符的随机字符串,用于生成安全令牌;开发环境默认DEVJWTSECRET |
PORT | Integer | 是 | 服务器监听端口 |
需要强调的是:DATABASE_URL、WASP_WEB_CLIENT_URL、WASP_SERVER_URL、JWT_SECRET、PORT这些变量在开发时由 Wasp 自动填充,生产环境则必须显式设置,缺失任何一个都会导致服务器启动失败。此外,如果你使用了 SMTP、SendGrid、Mailgun、Resend 等邮件发送器,或 Google/GitHub 等 OAuth 外部登录,还要额外配置对应的密钥类环境变量(完整清单见 project/env-vars.md)。
第三步:部署 Web 客户端(前端)
客户端是一个纯静态站点,需要先用生产构建命令把它编译成静态文件。在.wasp/build/web-app/目录下执行:
cd .wasp/build/web-app npm install && REACT_APP_API_URL=<url_to_wasp_backend> npm run build其中<url_to_wasp_backend>是前面已部署的服务器地址。构建结果位于.wasp/build/web-app/build/,是一堆静态文件,因此可以把它部署到任何静态托管平台(Netlify、Cloudflare 等)。
两个必须注意的细节:
- 如果你在项目中定义了其他客户端环境变量(开发时写在
.env.client里),生产构建时必须一并加到命令中,例如REACT_APP_SOME_VAR=somevalue npm run build。因为客户端变量是构建期注入进静态代码的,部署后在托管平台上设置会被忽略。 - 客户端变量注入到 JS 代码后对所有人可见,绝不能存放密钥(如 API 密钥应放在服务器环境变量中)。
第四步:部署数据库
只要提供一个可从服务器访问的 PostgreSQL 实例,并把正确的DATABASE_URL交给服务器即可。具体数据库的创建方式取决于云平台——Fly.io 和 Railway 都提供了托管 PostgreSQL,见下文各节。
Fly.io:部署服务器并托管数据库
Fly.io 负责托管服务器与数据库两部分(部署方法见 paas.md 的 Fly.io 一节)。如果你更希望由 Wasp CLI 一条命令完成全部部署,也可以使用 Wasp Deploy for Fly.io,后文有专门介绍。
前置条件
- 注册 Fly.io 账号;
- 安装
flyCLI; - 使用
flyCLI 登录:可用fly auth whoami检查登录状态,未登录时执行fly auth login。
初始化 Fly.io 应用(每个 Wasp 应用只需一次)
首先确保已经执行过wasp build,然后进入构建产物目录:
cd .wasp/build运行 launch 命令来创建新应用并生成fly.toml:
fly launch --remote-only命令会交互式地询问一系列问题,例如选择区域、是否需要数据库。针对 Wasp 应用,两个回答很关键:
- 对"Would you like to set up a PostgreSQL database now?"回答yes,并选择Development,Fly.io 会自动为你设置好
DATABASE_URL; - 对"Would you like to deploy now?"(以及后续附加问题)回答no——因为我们还要先配置好几个环境变量。
数据库初始化失败怎么办?如果创建应用失败,先用
fly apps destroy <app-name>清理,再重试。Fly 不允许同名创建多个应用。数据库部署成功后,可在 Fly.io 仪表盘的 Machines 区域看到它。
接下来把生成的fly.toml复制回 Wasp 项目根目录保存(防止被后续wasp build清掉):
cp fly.toml ../../然后为服务器设置几个关键环境变量:
fly secrets set PORT=8080 fly secrets set JWT_SECRET=<random_string_at_least_32_characters_long> fly secrets set WASP_WEB_CLIENT_URL=<url_of_where_client_will_be_deployed> fly secrets set WASP_SERVER_URL=<url_of_where_server_will_be_deployed>提示:如果客户端 URL 还没确定,不必担心——
WASP_WEB_CLIENT_URL可以在部署完客户端后再设置。如果你的应用启用了 Google/GitHub 等外部认证方式,还需要额外设置这些认证方式各自要求的密钥环境变量(参考 auth/social-auth 相关文档)。
想确认 secrets 是否设置成功,运行fly secrets list。注意终端里显示的是哈希后的版本,用于保护敏感数据。
部署到 Fly.io 应用
仍在.wasp/build/目录下执行:
fly deploy --remote-only --config ../../fly.toml这会构建并部署 Wasp 后端到https://<app-name>.fly.dev。之后如果你还没部署客户端,可以部署好客户端后用fly secrets set WASP_WEB_CLIENT_URL=<url_of_deployed_client>补上客户端地址。客户端建议用 Netlify(见下文),当然任何静态托管平台都可以。
一些常用的fly运维命令:
fly logs # 查看日志 fly secrets list # 查看已设置的 secrets fly ssh console # 进入服务器容器调试重新部署:fly.toml的三种保存策略
每次执行wasp build都会清空.wasp/build/目录,里面存放的fly.toml(如果有)会被删除。官方提供了三种应对方案:
- 把
fly.toml复制到版本化目录(如 Wasp 项目根目录),部署时用fly deploy --config <path>显式指定,如上文--config ../../fly.toml的做法; - 每次
wasp build前备份fly.toml,构建后复制回.wasp/build/——只要文件在位,就不需要再指定--config; - 用
fly config save -a <app-name>从 Fly.io 远端状态重新生成fly.toml。
仓库中真实生成的fly.toml示例可以参考 examples/ask-the-documents/fly-server.toml:它包含app名称、primary_region、HTTP 服务的internal_port = 8080、HTTPS 强制跳转、机器自动启停,以及 1 vCPU / 1GB 内存的虚拟机规格——这也印证了服务器需要在PORT=8080上监听。
Railway:一站式部署服务器、客户端与数据库
Railway 可以同时托管 Wasp 的三件套(服务器、客户端、数据库),详见 paas.md 的 Railway 一节。同样地,你也可以选择 Wasp Deploy for Railway 一键部署。
前置条件
- 在项目目录执行
wasp build确保应用已构建; - 注册 Railway 账号;
- 安装 Railway CLI;
- 执行
railway login,浏览器会打开完成认证。
创建 Railway 项目
- 打开 Railway 仪表盘,点击New Project,在下拉菜单中选择Deploy PostgreSQL;
- 项目创建后,点击右上角Create按钮,选择Empty Service;
- 点击新服务,改名为
server; - 再创建一个空服务,命名为
client; - 点击顶部的Deploy按钮使改动生效。
为两个服务生成域名
- 进入
server实例的Settings标签页,点击Generate Domain; - 端口填
8080,点击Generate Domain; - 对
client服务执行同样操作; - 复制两个域名,稍后要用。
部署服务器
进入构建目录:
cd .wasp/build把
.wasp/build关联到刚创建的 Railway 项目:railway link按提示选择
server服务。在 Railway 仪表盘的
server服务Variables标签页配置环境变量:- 点击Variable reference,选择
DATABASE_URL(会自动填入正确值); - 添加
WASP_WEB_CLIENT_URL,值为client域名,如https://client-production-XXXX.up.railway.app(必须带https://前缀); - 添加
WASP_SERVER_URL,值为server域名,如https://server-production-XXXX.up.railway.app(同样必须带https://前缀); - 添加
JWT_SECRET,值为至少 32 字符的随机字符串; - 若启用了外部认证,还需补充对应 OAuth 的环境变量。
- 点击Variable reference,选择
推送并部署:
railway up --ci--ci标志用于把日志输出限制为仅构建过程。Railway 会自动定位.wasp/build中的Dockerfile并部署服务器。
部署客户端
进入前端构建目录:
cd web-app以服务器域名为
REACT_APP_API_URL执行生产构建:npm install && REACT_APP_API_URL=<url_to_wasp_backend> npm run build关联客户端构建目录到
client服务:cd build railway link部署客户端构建产物:
railway up --ci按提示选择
client服务。Railway 检测到index.html后会把客户端作为静态站点部署。
至此部署完成。回到 Railway 仪表盘,可以看到三个服务:PostgreSQL、Server、Client。
更新与重新部署
当代码有更新需要重新上线时:
- 执行
wasp build重新构建; - 进入
.wasp/build,用railway up --ci重新部署服务器; - 进入
.wasp/build/web-app,重新执行npm install && REACT_APP_API_URL=<url_to_wasp_backend> npm run build,再cd build && railway up --ci重新部署客户端。
Heroku:容器化部署服务器与托管数据库
Heroku 负责服务器与数据库(详见 paas.md 的 Heroku 一节)。你需要 Heroku 账号、herokuCLI 和dockerCLI。用heroku whoami检查登录状态,未登录则执行heroku login。
创建 Heroku 应用(每个 Wasp 应用只需一次)
除非要部署到已有的 Heroku 应用,否则新建一个:
heroku create <app-name>如果没有外部 PostgreSQL 可用,就在 Heroku 上新建数据库并挂载到应用:
heroku addons:create --app <app-name> heroku-postgresql:essential-0⚠️ 费用提示:
essential-0是 Heroku 提供的最便宜的数据库实例,价格为 $5/月。注意在动手前确认是否符合你的预算预期。
Heroku 会自动为你设置DATABASE_URL环境变量(若使用外部数据库则需自行配置)。PORT也会由 Heroku 提供,因此只需再设置其余三个变量:
heroku config:set --app <app-name> JWT_SECRET=<random_string_at_least_32_characters_long> heroku config:set --app <app-name> WASP_WEB_CLIENT_URL=<url_of_where_client_will_be_deployed> heroku config:set --app <app-name> WASP_SERVER_URL=<url_of_where_server_will_be_deployed>同样地,WASP_WEB_CLIENT_URL可以在客户端部署完成后再设置。
部署 Heroku 应用
确认已执行过wasp build后,进入构建目录(假设当前在 Wasp 项目根目录):
cd .wasp/build登录 Heroku 容器镜像仓库:
heroku container:login把应用 stack 设为container,以便以 Docker 容器方式部署:
heroku stack:set container --app <app-name>构建 Docker 镜像并推送:
heroku container:push --app <app-name> web这一步并不会立即部署应用。首次推送可能耗时较长,因为没有缓存的 Docker 层。推送完成后,部署镜像并重启应用:
heroku container:release --app <app-name> web后端就此上线,地址形如https://<app-name>-XXXX.herokuapp.com。用以下命令查看确切的 URL 与日志:
heroku info --app <app-name> heroku logs --tail --app <app-name>使用 pg-boss 任务的应用:Heroku 专属配置
如果你的应用使用了以pg-boss作为执行器的 Jobs(后台任务),部署到 Heroku 时需要额外设置一个环境变量:
PG_BOSS_NEW_OPTIONS={"connectionString":"<REGULAR_HEROKU_DATABASE_URL>","ssl":{"rejectUnauthorized":false}}原因在于 pg-boss 依赖pg扩展,默认不会通过 SSL 连接数据库,而 Heroku 强制要求 SSL;同时 Heroku 使用自签名证书,必须显式关闭证书校验。这一环境变量的完整含义(包括archiveCompletedAfterSeconds、deleteAfterDays等更多 PgBoss 初始化参数)可参考 advanced/jobs.md 的PG_BOSS_NEW_OPTIONS一节——需要提醒的是,设置该变量会覆盖 Wasp 的所有默认值,因此connectionString必须包含在内。
Netlify:免费静态托管客户端
Netlify 是很多场景下免费的静态托管方案,适用于部署 Wasp 的客户端(详见 paas.md 的 Netlify 一节)。需要 Netlify 账号与 CLI:用npx netlify-cli status检查登录状态,未登录执行npx netlify-cli login。
先确保执行过wasp build,然后构建 Web 客户端:
cd .wasp/build/web-app npm install && REACT_APP_API_URL=<url_to_wasp_backend> npm run build部署(第一次):
npx netlify-cli deploy按提示认真操作:决定创建新应用还是使用已有应用、选择应用所属团队等。确认无误后发布到生产环境:
npx netlify-cli deploy --prod客户端将上线于https://<app-name>.netlify.app。记得把该 URL 设置为服务器环境中的WASP_WEB_CLIENT_URL。
⚠️ SPA 重定向配置按上述流程部署时,Netlify CLI 会使用 Wasp 默认生成的
.wasp/build/web-app/下的netlify.toml文件,它正确配置了把 URL 重定向到index.html。这一点很重要——Wasp 是单页应用(SPA),路由必须由客户端处理。 如果你改用其他方式(例如在 CI 中部署),务必确保 Netlify 能拿到netlify.toml,或者手动在 Netlify 上配置 URL 重定向规则。
通过 GitHub Actions 自动部署到 Netlify
在仓库中新建.github/workflows/deploy.yaml(文件名可改,扩展名保持 yaml 即可),示例配置如下(来自官方文档 paas.md):
name: Deploy Client to Netlify on: push: branches: - main # Deploy on every push to the main branch jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v2 - name: Setup Node.js id: setup-node uses: actions/setup-node@v4 with: node-version: '20' - name: Install Wasp run: curl -sSL https://get.wasp.sh/installer.sh | sh -s -- -v 0.16.0 # Change to your Wasp version - name: Wasp Build run: wasp build - name: Install dependencies and build the client run: | cd ./.wasp/build/web-app npm install REACT_APP_API_URL=${{ secrets.WASP_SERVER_URL }} npm run build - name: Deploy to Netlify run: | cd ./.wasp/build/web-app npx netlify-cli@17.36.1 deploy --prod --dir=build --auth=$NETLIFY_AUTH_TOKEN --site=$NETLIFY_SITE_NAME env: NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} NETLIFY_SITE_NAME: netlify-site-name需要预先准备并存入 GitHub Repository Secrets 的变量:
NETLIFY_AUTH_TOKEN:在 Netlify 控制台生成的 Personal Access Token;NETLIFY_SITE_NAME:你的 Netlify 项目名;WASP_SERVER_URL:后端服务器 URL,一般只有部署完成后端后才有值;后端未部署时可跳过该变量,但要意识到依赖后端的功能可能不可用。
Cloudflare:用 Wrangler 部署到 Cloudflare Pages
Cloudflare Pages 提供免费静态托管,适合部署 Wasp 客户端(详见 paas.md 的 Cloudflare 一节)。需要 Cloudflare 账号,并登录其 CLI(Wrangler):
npx wrangler login同样先执行wasp build,再构建 Web 客户端(参考上文 Netlify 一节)。然后定位到.wasp/build/web-app目录,运行:
npx wrangler pages deploy ./build --commit-dirty=true --branch=main按提示选择创建新应用还是使用已有应用。客户端将上线于https://<app-name>.pages.dev。记得把该 URL 设置为服务器环境中的WASP_WEB_CLIENT_URL。
SPA 重定向:Cloudflare 会自动把所有路径重定向到
index.html——Wasp 客户端是 SPA,必须由客户端处理路由,因此这一点开箱即用。
通过 GitHub Actions 自动部署到 Cloudflare Pages
同样在.github/workflows/deploy.yaml中添加工作流(官方示例 paas.md):
name: Deploy Client to Cloudflare on: push: branches: - main # Deploy on every push to the main branch jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v2 - name: Setup Node.js id: setup-node uses: actions/setup-node@v4 with: node-version: '20' - name: Install Wasp run: curl -sSL https://get.wasp.sh/installer.sh | sh -s -- -v 0.16.0 # Change to your Wasp version - name: Wasp Build run: cd ./app && wasp build - name: Install dependencies and build the client run: | cd ./app/.wasp/build/web-app npm install REACT_APP_API_URL=${{ secrets.WASP_SERVER_URL }} npm run build - name: Deploy to Cloudflare Pages uses: cloudflare/wrangler-action@v3 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} command: pages deploy ./app/.wasp/build/web-app/build --project-name=${{ env.CLIENT_CLOUDFLARE_APP_NAME }} --commit-dirty=true --branch=main env: CLIENT_CLOUDFLARE_APP_NAME: cloudflare-pages-app-name需要准备的环境变量:
CLOUDFLARE_API_TOKEN与CLOUDFLARE_ACCOUNT_ID:在 Cloudflare 控制台获取,Token 需授予Cloudflare Pages: Read和Cloudflare Pages: Edit权限;CLIENT_CLOUDFLARE_APP_NAME:Cloudflare Pages 应用名,可先用npx wrangler pages project create <app-name>创建;WASP_SERVER_URL:后端服务器 URL,后端未部署时可跳过,但依赖后端的功能可能不可用。
更省事的方案:Wasp CLI 一键部署
上面介绍的都是手动部署流程。如果你希望用一条命令自动化完成"搭建服务、构建、部署"全流程,Wasp CLI 提供了wasp deploy命令(详见 wasp-deploy/overview.md):
wasp deploy <provider> launch my-wasp-app该命令会在云平台上创建所需的全部服务、构建 Wasp 应用并完成部署,是目前官方推荐的部署方式。当前支持 Fly.io 与 Railway 两个平台。
以 Fly.io 为例:
wasp deploy fly launch my-wasp-app mialaunch会依次执行setup、create-db、deploy,生成三个独立应用(my-wasp-app-client、my-wasp-app-server、my-wasp-app-db),并在项目根目录生成fly-server.toml与fly-client.toml两个配置文件——记得纳入版本控制,便于以后单命令重复部署。launch还会自动为服务器设置WASP_WEB_CLIENT_URL、WASP_SERVER_URL、DATABASE_URL、JWT_SECRET这些必需变量(见 _launch-command-env-vars.md)。如需补充 OAuth 等密钥,用--server-secret参数或在部署后执行wasp deploy fly cmd secrets set ... --context=server。
以 Railway 为例:
wasp deploy railway launch my-wasp-app它会基于项目名创建my-wasp-app-client、my-wasp-app-server两个服务和一个名为Postgres的数据库服务。后续更新只需运行wasp deploy fly deploy(Fly.io)或wasp deploy railway deploy <project-name>(Railway)。两个平台的完整命令参考分别见 wasp-deploy/fly.md 与 wasp-deploy/railway.md。
小结
一次 Wasp 生产部署的本质,就是把wasp build生成的"Node.js 服务器 + 静态客户端 + PostgreSQL"三件套分别交给合适的云平台:服务器与数据库交给 Fly.io、Railway 或 Heroku,客户端交给 Netlify、Cloudflare 等静态托管。无论选择哪条路径,生产环境的五个核心环境变量(DATABASE_URL、WASP_WEB_CLIENT_URL、WASP_SERVER_URL、JWT_SECRET、PORT)都必须显式配置,客户端变量必须在构建时注入,SPA 的index.html重定向必须得到保证。如果需要更快的上线体验,直接用wasp deploy fly launch或wasp deploy railway launch即可一键完成全栈部署。
【免费下载链接】waspThe batteries-included full-stack framework for the AI era. Develop JS/TS web apps (React, Node.js, and Prisma) using declarative code that abstracts away complex full-stack features like auth, background jobs, RPC, email sending, end-to-end type safety, single-command deployment, and more.项目地址: https://gitcode.com/GitHub_Trending/wa/wasp
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考