Deployment Guide
This guide covers deploying the full Novatip stack to testnet and then promoting to mainnet. Follow the steps in order - each layer depends on the one below it.
Deployment Order
1. novatip-contracts (Stellar testnet / mainnet)
2. novatip-backend (any Node.js host: Railway, Render, Fly.io)
3. novatip-web (Vercel or Cloudflare Pages)
4. novatip-docs (Cloudflare Pages - see CI/CD guide)
1. Deploy the Contract
Testnet
cd novatip-contracts
cp .env.example .env
# Edit .env:
# NETWORK=testnet
# SOURCE=my-identity
# ADMIN=G...
# USDC_TOKEN=CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA
make build
./scripts/deploy.sh
cat .contract-id # save this value
Mainnet
# Edit .env:
# NETWORK=mainnet
# USDC_TOKEN=CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75
./scripts/deploy.sh
Mainnet deployment costs real XLM. Ensure your SOURCE account is funded
with enough XLM to cover contract deployment fees (approximately 1-2 XLM).
2. Deploy the Backend
Environment variables for production
Set these in your hosting platform's secrets manager:
NODE_ENV=production
DATABASE_URL=postgresql://user:pass@host:5432/novatip
REDIS_URL=redis://host:6379
JWT_SECRET=<64-char random string>
STELLAR_NETWORK=mainnet
SOROBAN_RPC_URL=https://mainnet.stellar.validationcloud.io/v1/soroban/rpc
HORIZON_URL=https://horizon.stellar.org
NETWORK_PASSPHRASE=Public Global Stellar Network ; September 2015
TIP_SPLITTER_CONTRACT_ID=C...
USDC_CONTRACT_ID=CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75
INDEXER_START_LEDGER=<current ledger sequence>
RESEND_API_KEY=re_...
APP_BASE_URL=https://novatip.xyz
Generate a secure JWT secret:
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
Database migrations
Run migrations before starting the server on each deploy:
npx prisma migrate deploy
node dist/app.js
The Dockerfile handles this automatically via the CMD instruction.
Recommended hosts
| Platform | Notes |
|---|---|
| Railway | Easiest - detects Dockerfile automatically, managed PostgreSQL + Redis |
| Render | Free tier available, managed PostgreSQL add-on |
| Fly.io | Best performance, requires fly.toml config |
| VPS (DigitalOcean, Hetzner) | Most control, requires manual setup |
Railway (recommended for quick start)
npm install -g @railway/cli
railway login
railway init
railway up
Set all environment variables in the Railway dashboard under Settings > Variables.
3. Deploy the Frontend
Environment variables
NEXT_PUBLIC_API_URL=https://api.novatip.xyz/api/v1
NEXT_PUBLIC_STELLAR_NETWORK=mainnet
NEXT_PUBLIC_TIP_SPLITTER_CONTRACT_ID=C...
NEXT_PUBLIC_USDC_CONTRACT_ID=CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75
Vercel (recommended)
npm install -g vercel
cd novatip-web
vercel deploy --prod
Or connect your GitHub repo in the Vercel dashboard for automatic deploys
on every push to main.
Cloudflare Pages
npm run build
# Deploy the `out/` directory to Cloudflare Pages
In the Cloudflare Pages dashboard:
- Build command:
npm run build - Build output directory:
.next - Add all
NEXT_PUBLIC_*environment variables
For Cloudflare Pages with Next.js, install the
@cloudflare/next-on-pages adapter for full edge compatibility.
4. Custom Domain Setup
Backend API (api.novatip.xyz)
Add a CNAME or A record pointing api.novatip.xyz to your hosting
provider's endpoint. Enable HTTPS (most providers do this automatically).
Frontend (novatip.xyz)
Add your domain in the Vercel or Cloudflare Pages dashboard. Both automatically provision free TLS certificates via Let's Encrypt.
5. Post-Deployment Checklist
After deploying to mainnet, verify:
- Health check:
GET https://api.novatip.xyz/api/v1/healthreturns{ "status": "ok" } - Indexer is running: check backend logs for
[indexer] resuming from ledger - Contract resolver:
GET https://api.novatip.xyz/api/v1/resolve/alicereturns creator data - Tip page loads:
https://novatip.xyz/@alicerenders without errors - Wallet connects: Freighter connects on mainnet
- Test tip: send a small $0.10 USDC tip and confirm it reaches the recipient
- Dashboard updates: tip appears in the creator's recent feed within 10 seconds
- QR code downloads:
GET https://api.novatip.xyz/api/v1/qr/alice/pngreturns a PNG
Environment Promotion
To promote from testnet to mainnet without rebuilding:
- Update
STELLAR_NETWORK=mainnetin the backend env - Update
SOROBAN_RPC_URLandHORIZON_URLto mainnet endpoints - Update
TIP_SPLITTER_CONTRACT_IDto the mainnet contract ID - Update
USDC_CONTRACT_IDto the mainnet USDC SAC - Set
INDEXER_START_LEDGERto the current mainnet ledger sequence - Restart the backend process
- Update
NEXT_PUBLIC_STELLAR_NETWORK=mainnetandNEXT_PUBLIC_TIP_SPLITTER_CONTRACT_ID - Redeploy the frontend