Wasp 单命令全栈部署指南:wasp deploy从入门到源码级解析
【免费下载链接】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 deploy展开,讲解如何用一条命令把 Wasp 全栈应用(React 客户端 + Node.js 服务端 + PostgreSQL 数据库)部署到 Fly.io 或 Railway,并深入剖析launch命令背后自动化的服务创建、构建、部署流程,以及环境变量、自定义域名、CI/CD 集成等实战细节。读完本文,你将掌握 Wasp 应用从本地开发到云端上线的完整闭环,并理解其底层实现原理。
wasp deploy是什么
Wasp 的部署命令在设计上有两个核心目标:把手工部署流程自动化,并成为 Wasp 应用官方推荐的部署方式。与手工在云平台上创建服务、配置数据库、构建镜像、设置环境变量的繁琐过程相比,wasp deploy由 Wasp CLI 一键接管全部环节。
它的用法非常简洁:
wasp deploy <provider> launch my-wasp-app这条命令会完成三件事:
- 在目标云平台上创建应用所需的全部服务(客户端、服务端、数据库);
- 构建你的 Wasp 应用(包括客户端与服务端);
- 把构建产物部署上线。
从仓库源码可以看到,wasp deploy子命令体系定义在 waspc/data/packages/deploy/src/index.ts,入口程序注册了两个 provider 子命令(fly与railway),整个部署 CLI 基于commander构建,并透传了--wasp-exe与--wasp-project-dir两个隐藏参数来定位 Wasp 可执行文件与项目目录:
program .name("wasp deploy") .description("CLI for deploying Wasp apps to various clouds") .allowUnknownOption(); program.addCommand(createFlyCommand()); program.addCommand(createRailwayCommand());支持的部署平台
Wasp Deploy 目前支持以下两个自动化部署平台(对应文档页面 Fly.io 与 Railway):
- Fly.io:面向全球的容器化应用运行平台,可把应用部署在世界各地的数据中心,通过 Anycast 网络就近响应用户;
- Railway:自带数据库与服务编排能力的云端开发平台,界面直观、基础设施自动化程度高。
两个平台的 CLI 命令结构完全对称,均为wasp deploy <provider> <子命令> [参数],学习成本很低。
理解launch命令背后的自动化流程
launch是wasp deploy最常用的"一键上线"命令,但它本质上是一个组合命令,内部按顺序调用了多个子命令。搞清楚这一点,你就能在需要分步执行(例如先建库、再单独发布)时得心应手。
Fly.io 上的launch
对 Fly.io 而言,wasp deploy fly launch <app-name> <region>等价于依次执行:
wasp deploy fly setup <app-name> <region> wasp deploy fly create-db <region> wasp deploy fly deploy即:注册服务 → 创建数据库 → 部署上线。在源码 waspc/data/packages/deploy/src/providers/fly/commands/launch/launch.ts 中可以看到这一调用链的直接实现——launch()依次调用setup()、createDb()和deploy(),并且会先检查项目里是否已存在fly-server.toml/fly-client.toml,若已存在则直接报错,提醒你launch只应在全新 Fly 项目上运行一次。
Railway 上的launch
对 Railway 而言,wasp deploy railway launch <project-name>等价于:
wasp deploy railway setup <project-name> wasp deploy railway deploy <project-name>区别在于 Railway 的数据库服务由setup一并创建,无需单独的create-db子命令。
launch自动配置的环境变量
运行launch命令时,Wasp CLI 已经"知道"你的 Wasp 应用各部分组成,会自动为服务端应用设置以下关键环境变量,这也是全栈应用能在云上正常连通的关键:
| 环境变量 | 作用 |
|---|---|
WASP_WEB_CLIENT_URL | 客户端应用地址,客户端与服务端连通所必需 |
WASP_SERVER_URL | 服务端应用地址,客户端与服务端连通所必需 |
DATABASE_URL | 数据库连接串,服务端连接数据库所必需 |
JWT_SECRET | 认证密钥,Wasp 认证功能正常工作所必需 |
除此之外,如果你的应用还需要其他服务端环境变量(如 Google 登录的GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET),可以在launch或setup命令中通过--server-secret FOO=BAR传入;客户端环境变量则需要在运行部署命令前,以环境变量的形式注入当前终端会话(详见下文对应平台小节)。关于客户端环境变量的完整说明,可参考 env-vars 文档。
部署到 Fly.io
Fly.io 适合希望把应用就近部署到全球多个数据中心、并享受成熟容器化生态的场景。以下内容完整对应 Fly.io 部署文档。
前置条件
在开始之前,你需要准备:
- 一个 Fly.io 账户;
- 注意:Fly 要求先绑定支付方式才能部署超过两个应用,而一个 Wasp 应用需要三个 Fly 应用(客户端
-client、服务端-server、数据库-db),因此绑卡是必需步骤; - 在本地安装
flyCLI。
发起部署
一条命令完成上线:
wasp deploy fly launch my-wasp-app dfw建议:命令运行期间不要 Ctrl-C 或关闭终端,等待全部步骤执行完毕。
需要牢记两点:
- 应用名(如
my-wasp-app)在整个 Fly 平台范围内必须唯一,否则部署会失败; - 如果你的 Fly 账户属于多个组织,需要额外指定
--org <org-slug>参数,可用fly orgs list查看你的组织 slug 列表。
上述命令中,my-wasp-app作为 basename(应用基名),dfw是部署区域(dfw即美国德克萨斯州达拉斯)。Wasp 会用这个基名创建三个独立应用,它们会同时出现在你的 Fly 控制台中:
my-wasp-app-clientmy-wasp-app-servermy-wasp-app-db
生成的两个 TOML 配置文件
部署成功后,Wasp 会在项目根目录生成两个新文件:
fly-server.tomlfly-client.toml
建议把这两个文件纳入版本控制,这样以后就能用单条命令反复部署。仓库中的示例项目 examples/ask-the-documents 就真实带有这两个文件,其 fly-server.toml 内容大致如下:
app = 'ask-the-documents-server' primary_region = 'cdg' [build] [http_service] internal_port = 8080 force_https = true auto_stop_machines = 'stop' auto_start_machines = true min_machines_running = 1 processes = ['app'] [[vm]] memory = '1gb' cpu_kind = 'shared' cpus = 1而 fly-client.toml 结构相同,只是服务名、内部端口(客户端为8043)和min_machines_running(客户端可为0)有所不同。你可以直接编辑这两个 TOML 文件来进一步定制 Fly 部署(如调整 VM 规格),Wasp 在deploy时会读取它们。若需要同时维护多个应用(如dev、staging环境),可用--fly-toml-dir <绝对路径>指向不同的目录。
从源码看,TOML 文件的读写逻辑集中在 waspc/data/packages/deploy/src/providers/fly/tomlFile.ts:部署时会把项目里的fly-server.toml/fly-client.toml复制为当前目录的fly.toml交给 flyctl 使用,再从中解析出app名称,反推 basename。
配置自定义域名
为应用绑定自定义域名共三步(以下命令中的mycoolapp.com请替换为你自己的域名):
第一步:为 Fly 客户端应用创建证书:
wasp deploy fly cmd --context client certs create mycoolapp.com该命令会输出添加 DNS 记录所需的指引,大致形如:
You can direct traffic to mycoolapp.com by: 1: Adding an A record to your DNS service which reads A @ 66.241.1XX.154 You can validate your ownership of mycoolapp.com by: 2: Adding an AAAA record to your DNS service which reads: AAAA @ 2a09:82XX:1::1:ff40第二步:去你的域名服务商处添加 DNS 记录——通常是为@添加一条 A 记录和一条 AAAA 记录,值取上一步命令的输出。
第三步:为服务端应用设置WASP_WEB_CLIENT_URL环境变量,保持 CORS 配置与域名一致:
wasp deploy fly cmd --context server secrets set WASP_WEB_CLIENT_URL=https://mycoolapp.com完成以上三步,应用即可通过https://mycoolapp.com访问。
添加www子域名:若还希望支持https://www.mycoolapp.com,先为www子域生成证书:
wasp deploy fly cmd --context client certs create www.mycoolapp.com再为www添加一条指向根域的 CNAME 记录:
| Type | Name | Value | TTL |
|---|---|---|---|
| CNAME | www | mycoolapp.com | 3600 |
注意:同时使用
www与non-www两个域名时,必须更新服务端的 CORS 配置以同时允许两个域名,否则会出现跨域错误。
服务端与客户端环境变量
服务端密钥:除了launch/setup时用--server-secret设置外,应用上线后可用secrets set命令补充:
wasp deploy fly cmd secrets set GOOGLE_CLIENT_ID=<...> GOOGLE_CLIENT_SECRET=<...> --context=server客户端环境变量:如果你的应用定义了客户端环境变量,需要在每次运行部署命令前注入终端会话,例如:
REACT_APP_ANOTHER_VAR=somevalue wasp deploy fly launch my-wasp-app dfw或
REACT_APP_ANOTHER_VAR=somevalue wasp deploy fly deploy注意:每次部署都必须带上,而不只是首次。为避免遗忘,建议在package.json中固化一个部署脚本:
{ "scripts": { "deploy": "REACT_APP_ANOTHER_VAR=somevalue wasp deploy fly deploy" } }之后运行npm run deploy即可完成部署。
选择部署区域
Fly.io 在全球 34 个区域运行应用,并通过 Anycast 网络让用户就近接入。可通过如下命令查看所有可用区域:
fly platform regions在launch命令中,区域参数必须是三位字母代码(源码中会统一转为小写并校验合法性),如dfw(达拉斯)、cdg(巴黎)等。
多组织场景
多组织账户可显式指定组织:
wasp deploy fly launch my-wasp-app dfw --org hive本地构建与远程构建
Fly.io 同时支持本地构建与远程构建 Docker 容器。为了简单与可复现,CLI 默认使用Fly 远程构建器。如需本地构建,为launch或deploy增加--build-locally选项即可。
使用自定义 PostgreSQL 数据库
Wasp 默认使用 PostgreSQL 18(与开发环境主版本一致)创建 Fly 数据库,镜像为flyio/postgres-flex:18(该默认值定义在 waspc/data/packages/deploy/src/providers/fly/index.ts 中,并刻意与 Wasp 开发数据库的主版本保持同步)。若应用需要其他 PostgreSQL 镜像(例如添加 PostGIS 扩展),使用--db-image <docker-image>指定。
自定义镜像必须与 Fly 平台兼容;最稳妥的做法是基于官方镜像flyio/postgres-flex构建。数据库镜像只需在创建数据库时指定一次:
wasp deploy fly create-db <region> --db-image <custom-postgres-image> wasp deploy fly launch <app-name> <region> --db-image <custom-postgres-image>Fly.io 命令速查(API Reference)
launch:一键完成setup+create-db+deploy。
wasp deploy fly launch <app-name> <region><app-name>(必填):应用名;<region>(必填):部署区域。
launch支持数据库选项(见下)、--server-secret/--client-secret、--build-locally以及--custom-server-url(当客户端需要连接不同服务端地址、例如服务端使用自定义域名时使用)。
setup:在 Fly 上注册客户端与服务端应用,并配置环境变量。只执行一次,不会触发部署:
wasp deploy fly setup <app-name> <region><app-name>(必填)、<region>(必填);- 运行后会生成
fly-server.toml与fly-client.toml,请纳入版本控制; - 多应用场景可用
--fly-toml-dir <abs-path>指向不同目录; - 注意:
setup每个应用只能执行一次,重复执行会在 Fly 上创建多余应用。
create-db:为应用创建数据库,每个应用只需一次:
wasp deploy fly create-db <region><region>(必填);- 重复执行会创建多个数据库,而应用只需要一个。
deploy:将构建好的客户端与服务端推送上线,用于更新已部署应用:
wasp deploy fly deploy支持--skip-client(不部署客户端)、--skip-server(不部署服务端)、--build-locally与--custom-server-url。
cmd:在客户端或服务端上下文中执行任意 flyctl 命令:
wasp deploy fly cmd secrets list --context server必须通过--context指定client或server。
Fly 数据库选项一览
所有数据库选项均为可选项:
| 选项 | 默认值 | 说明 |
|---|---|---|
--db-vm-size <vmSize> | shared-cpu-1x | 数据库 VM 规格,决定 CPU 种类、核数与内存 |
--db-vm-memory <vmMemory> | 由 VM 规格决定 | 数据库 VM 内存(MB) |
--db-vm-cpus <vmCpus> | 由 VM 规格决定 | 数据库 VM CPU 核数 |
--db-vm-cpu-kind <vmCpuKind> | 由 VM 规格决定 | 数据库 VM CPU 种类 |
--db-initial-cluster-size <size> | 1 | 数据库初始机器数量 |
--db-volume-size <size> | 1 | 数据库卷大小(GB) |
--db-image <image> | flyio/postgres-flex:18 | PostgreSQL Docker 镜像 |
部分应用需要比 Fly 默认更高的数据库内存,此时请在创建数据库时使用--db-vm-memory。注意 Fly 只接受特定组合的 CPU 种类、核数与内存,自定义时要参照 Fly 的机器规格规则选择匹配的值。
部署到 Railway
Railway 提供开箱即用的数据库与服务编排能力,适合追求界面化操作与快速上手的场景。以下内容完整对应 Railway 部署文档。
前置条件
- 注册 Railway 账户;
- 在本地安装
railwayCLI。
发起部署
wasp deploy railway launch my-wasp-app注意事项:
- 项目名(如
my-wasp-app)在你的 Railway 账户内必须唯一,否则部署失败(这是当前 Wasp CLI 与 Railway 集成的一个已知限制); - 如果你属于多个 Railway 组织,CLI 会提示你选择部署目标组织。
项目名会作为客户端与服务端服务名的基名:
my-wasp-app-clientmy-wasp-app-server
数据库服务则固定命名为Postgres,与项目名无关。
配置自定义域名
第一步:在 Railway 控制台为客户端服务添加域名:
- 进入 Railway dashboard;
- 选择项目(如
my-wasp-app); - 点击客户端服务(如
my-wasp-app-client); - 进入Settings标签页,点击Custom Domain;
- 输入域名(如
mycoolapp.com)与端口8080; - 点击Add Domain。
第二步:更新 DNS 记录,为域名添加一条 CNAME 记录,指向上一步获得的地址(具体操作取决于你的域名服务商)。
第三步:为避免 CORS 错误,在 Railway 控制台的服务端服务(my-wasp-app-server)的Variables标签页中,将WASP_WEB_CLIENT_URL更新为新的客户端地址(如https://mycoolapp.com)。
完成以上步骤,应用即可通过https://mycoolapp.com访问。
Railway 命令速查(API Reference)
launch:一键完成setup+deploy:
wasp deploy railway launch <project-name><project-name>(必填):项目名。
launch支持以下扩展选项:
--existing-project-id <railway-project-id>:默认情况下 Wasp CLI 会新建名为<project-name>的 Railway 项目;若想复用已有项目,传入其 ID;--workspace <railway-workspace-id-or-name>:默认会交互式询问工作区,可用此参数跳过提示直接指定;--server-secret FOO=BAR:设置服务端密钥;--db-image <docker-image>与--db-volume-mount-path <path>:自定义 PostgreSQL 数据库;--custom-server-url https://api.myapp.com:自定义服务端地址。
deploy:部署或更新客户端与服务端:
wasp deploy railway deploy <project-name>- 会使用与 Wasp 项目目录关联的 Railway 项目;若尚未关联,命令会失败并提示先运行
setup; - CI 场景可用
--existing-project-id <railway-project-id>显式指定项目 ID; - 支持
--skip-client(不部署客户端)与--skip-server(不部署服务端)。
setup:创建客户端、服务端与数据库服务,并配置环境变量。不会触发部署:
wasp deploy railway setup <project-name>- 服务命名为
<project-name>-client与<project-name>-server,同时创建名为Postgres的 PostgreSQL 数据库服务; - 同样支持
--existing-project-id与--workspace; - 注意:
setup每个应用只需执行一次(已存在的服务会被跳过,不会重复创建)。
Railway 环境变量
服务端密钥:可在launch/setup时用--server-secret设置;应用上线后,也可在 Railway 控制台服务端服务的Variables标签页补充。
客户端环境变量:与 Fly 一致,需要在每次运行部署命令前注入终端会话:
REACT_APP_ANOTHER_VAR=somevalue wasp deploy railway launch my-wasp-app同样建议写入package.json的部署脚本,避免遗忘:
{ "scripts": { "deploy": "REACT_APP_ANOTHER_VAR=somevalue wasp deploy railway deploy" } }Railway 自定义 PostgreSQL
Wasp 默认用 PostgreSQL 18 创建 Railway 数据库(与开发环境主版本一致),默认镜像为ghcr.io/railwayapp-templates/postgres-ssl:18,默认已内置 pgvector,数据存放在 Railway volume 中(挂载路径默认/var/lib/postgresql/data,可通过--db-volume-mount-path修改)。需要 PostGIS 等扩展时:
wasp deploy railway launch my-wasp-app --db-image postgis/postgis:18-3.6镜像只需在首次创建应用时指定一次。另外,这些命令创建的数据库无法使用 Railway 的 Database View 界面,如需浏览数据,可参考 连接生产数据库 文档,用wasp db studio直连生产库。
结合 CI/CD 实现提交即部署
wasp deploy <provider> launch在本地完成首次部署后,就可以在 CI/CD 流水线中用wasp deploy <provider> deploy实现"每次推送自动重新部署"。完整方案见 CI/CD 部署文档,核心流程包括:检出代码 → 安装 Node.js 与 Wasp CLI → 安装平台相关依赖(如 flyctl / railway CLI)→ 执行deploy命令,并在 CI 中配置平台 API Token。
Fly.io 的 CI 配置:需要组织级 token(fly tokens create org生成),存入仓库 secrets 的FLY_API_TOKEN:
name: Wasp Deploy on: push: branches: - main jobs: deploy: runs-on: ubuntu-latest env: WASP_VERSION: "{pinnedLatestWaspVersion}" steps: - uses: actions/checkout@v6 - name: Setup Node.js uses: actions/setup-node@v6 with: node-version: "{minimumNodeJsVersion}" - name: Install Wasp run: npm i -g @wasp.sh/wasp-cli@$WASP_VERSION - name: Install Flyctl uses: superfly/flyctl-actions/setup-flyctl@master - name: Deploy run: wasp deploy fly deploy env: FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}Railway 的 CI 配置:需要账户 token(在账户设置 Tokens 中生成,不绑定工作区),存入RAILWAY_API_TOKEN,并将RAILWAY_PROJECT_NAME与RAILWAY_PROJECT_ID配置到环境:
name: Wasp Deploy on: push: branches: - main jobs: deploy: runs-on: ubuntu-latest env: WASP_VERSION: "{pinnedLatestWaspVersion}" RAILWAY_PROJECT_NAME: my-project-name RAILWAY_PROJECT_ID: MY_PROJECT_ID steps: - uses: actions/checkout@v6 - name: Setup Node.js uses: actions/setup-node@v6 with: node-version: "{minimumNodeJsVersion}" - name: Install Wasp run: npm i -g @wasp.sh/wasp-cli@$WASP_VERSION - name: Install Railway CLI run: npm install -g @railway/cli - name: Deploy run: wasp deploy railway deploy $RAILWAY_PROJECT_NAME --existing-project-id $RAILWAY_PROJECT_ID env: RAILWAY_API_TOKEN: ${{ secrets.RAILWAY_API_TOKEN }}建议将 Wasp CLI 版本固定(如上例的$WASP_VERSION),避免新版本发布带来的意外变更。
从源码看wasp deploy的实现原理
部署 CLI 的实现位于 waspc/data/packages/deploy/src,整体结构清晰,可作为理解其原理的入口:
- 命令入口index.ts:用
commander组装fly与railway两个 provider 子命令; - Fly 命令定义providers/fly/index.ts:定义了
launch/setup/create-db/deploy/cmd五个子命令及其全部选项。可以观察到几个设计细节:- 默认数据库镜像被刻意固定为
flyio/postgres-flex:18,与 Wasp 开发数据库主版本保持一致,避免 flyctl 服务端默认镜像跨大版本升级带来的不兼容; - 每个子命令都通过
preAction钩子先执行ensureFlyReady()(确保本地 flyctl 可用)、assertValidWaspProject()(校验当前目录是合法 Wasp 项目),以及区域合法性校验; launch的组合语义、--build-locally(默认远程构建)、--org、--fly-toml-dir、--skip-client/--skip-server等选项都在这里注册;
- 默认数据库镜像被刻意固定为
- Railway 命令定义providers/railway/index.ts:结构上与 Fly 对称,默认数据库镜像为
ghcr.io/railwayapp-templates/postgres-ssl:18,并额外提供--db-volume-mount-path选项; - TOML 文件管理providers/fly/tomlFile.ts:负责
fly.toml与项目内fly-server.toml/fly-client.toml之间的复制、解析app名称并反推 basename——这就是"生成两个 TOML 文件并纳入版本控制后即可反复部署"的底层机制。
理解了这些源码,你就能明白:wasp deploy本质上是把"flyctl / railway CLI 手工操作 + Wasp 构建 + 环境变量编排"封装为一条声明式的命令,而launch的组合语义与 TOML 文件约定则是保证"一次上线、多次更新"可复现的关键设计。
总结
wasp deploy <provider> launch <app-name>是 Wasp 官方推荐的部署方式,一条命令完成服务创建、应用构建与上线;- 目前支持 Fly.io 与 Railway 两个平台,命令体系对称,
launch均为组合命令,可拆解为setup/create-db/deploy等原子步骤; - 部署时自动配置
WASP_WEB_CLIENT_URL、WASP_SERVER_URL、DATABASE_URL、JWT_SECRET四个关键环境变量;其余服务端密钥用--server-secret或secrets set设置,客户端变量需在每次部署时注入终端; - 自定义域名、数据库规格、构建方式等均有对应的 CLI 选项支持,且生成的 TOML 文件可纳入版本控制实现可复现部署;
- 首次
launch之后,即可在 CI/CD 中通过wasp deploy <provider> deploy实现推送即更新。
【免费下载链接】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),仅供参考