Deploying
This React/Node.js/Postgres app supports a one-command deploy to Fly.io or a manual deploy to any provider.
Fastest path: use the one-command deploy. Prefer another host or split front/back ends? See Deploying Manually below.
Deploying your app
Use the sequence below to deploy your app:
- Get your production API keys and environment variables
- Deploy your app easily to Fly.io or manually to any provider.
- Add the correct redirect URL’s to your social auth credentials
- Set up your production webhooks for either Stripe, UniBee, Lemon Squeezy
- Set your production environment variables on your deployed apps
- (Optional) Deploy your blog
Prerequisites
AWS S3 CORS
If you use AWS S3, add your production domain to the bucket CORS AllowedOrigins. See File Uploading guide.
Env vars checklist
Before deploying, confirm all keys and variables.
Payment Processor vars
In Payments Integration you used test keys and test product IDs. For production, repeat the same steps with live mode and add the live keys to the deployed environment.
Other vars
Many will match development, but double-check. Full list:
General:
DATABASE_URL
JWT_SECRET
WASP_WEB_CLIENT_URL
WASP_SERVER_URL
OpenAI:
OPENAI_API_KEY
SendGrid:
SENDGRID_API_KEY
Social auth:
GOOGLE_CLIENT_ID
GOOGLE_CLIENT_SECRET
GITHUB_CLIENT_ID
GITHUB_CLIENT_SECRET
Analytics:
REACT_APP_PLAUSIBLE_ANALYTICS_ID
PLAUSIBLE_API_KEY
PLAUSIBLE_SITE_ID
PLAUSIBLE_BASE_URL
REACT_APP_GOOGLE_ANALYTICS_ID
GOOGLE_ANALYTICS_CLIENT_EMAIL
GOOGLE_ANALYTICS_PROPERTY_ID
GOOGLE_ANALYTICS_PRIVATE_KEY
Note: convert the JSON private key to base64 first withecho -n "PRIVATE_KEY" | base64
See Analytics docs [link] for details
AWS S3:
AWS_S3_IAM_ACCESS_KEY
AWS_S3_IAM_SECRET_KEY
AWS_S3_FILES_BUCKET
AWS_S3_REGION
Deploying to Fly.io
Fly.io is a global app platform — great for SaaS because you can spin up for free, run frontend + backend together, scale easily, and deploy with a single command.
Use wasp deploy
to ship the whole stack—DB, server, and client—in a single command. For the step-by-step, follow the official Deploy to Fly with the Wasp CLI guide; work through it carefully to get live.
Setting Environment Variables
We're using some client-side env vars, so pass them to yourwasp deploy
commands to include them in the build.
REACT_APP_CLIENT_ENV_VAR_1=<...> REACT_APP_CLIENT_ENV_VAR_2=<...> wasp deploy
The deploy command handles the following server-side envs automatically:
DATABASE_URL
· PORT
· JWT_SECRET
· WASP_WEB_CLIENT_URL
· WASP_SERVER_URL
Deploying manually or to other providers
If you’d rather deploy the frontend and backend separately — or use your own host — see the Manual Deployment guide.
Client-side environment variables on manual builds
Append client-side vars to your build command, for example:
REACT_APP_CLIENT_ENV_VAR_1=<...> npm run build
Adding server redirect URLs to social auth
After deploying your server, add correct redirect URIs in each provider’s app settings. Use the Wasp docs for:
Setting up your production Stripe webhook
Follow these steps when preparing for production.
Stripe API versions
Your Stripe account is tied to the current API version at the time you create it — and that dictates webhook response formats and request expectations. Since this template assumes a particular version, your account’s version could differ. Test any change before deploying.
Reference in code:
export const stripe = new Stripe(process.env.STRIPE_API_KEY!, {
apiVersion: 'YYYY-MM-DD', // e.g. 2023-08-16
});
Steps to align versions:
- Find your default API version in Stripe dashboard under Developers
- Confirm it matches your
src/payment/stripe/stripeClient.ts
:
export const stripe = new Stripe(process.env.STRIPE_KEY!, {
apiVersion: 'YYYY-MM-DD', // e.g. 2023-08-16
});
- If they do not match, choose one of:
- If your dashboard’s default equals the latest API, upgrade the Stripe NPM package to the latest
- If your dashboard’s default is not the latest and you do not want to upgrade, install the Stripe NPM version that matches that date
How to find the NPM version that matches your default date:
- Note the date of your default API version in the developer dashboard
- Open the Stripe NPM package page and hover Published until you find the release matching your date
Install that exact package version:
npm install [email protected] # e.g. npm install [email protected]
Test your app thoroughly after changing the client version.
Creating your production webhook
- Go to https://dashboard.stripe.com/webhooks
- Click + add endpoint
3.Enter your endpoint URL which is your deployed server URL plus
/payments-webhook
For example:https://open-saas-wasp-sh-server.fly.dev/payments-webhook
- Select the events to listen to. Use the same events your webhook consumes as listed in
src/payment/stripe/webhookPayload.ts
- Reveal the signing secret on the webhook page
- Add this secret to your server environment as
STRIPE_WEBHOOK_SECRET
If deployed to Fly.io, run:
wasp deploy fly cmd --context server secrets set STRIPE_WEBHOOK_SECRET=whsec_...
Setting up your production Lemon Squeezy webhook
Your endpoint is your deployed server URL plus /payments-webhook
, for example:
https://open-saas-wasp-sh-server.fly.dev/payments-webhook
In the Lemon Squeezy Webhooks Dashboard:
- Click the + button
- Add the Callback URL
- Create a long random signing secret
- Add it as
LEMONSQUEEZY_WEBHOOK_SECRET
in your server production environment - Select at least these events:
order_created
subscription_created
subscription_updated
subscription_cancelled
- Save