Skip to main content

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
warning

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.

PlatformNotes
RailwayEasiest - detects Dockerfile automatically, managed PostgreSQL + Redis
RenderFree tier available, managed PostgreSQL add-on
Fly.ioBest performance, requires fly.toml config
VPS (DigitalOcean, Hetzner)Most control, requires manual setup
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
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
info

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/health returns { "status": "ok" }
  • Indexer is running: check backend logs for [indexer] resuming from ledger
  • Contract resolver: GET https://api.novatip.xyz/api/v1/resolve/alice returns creator data
  • Tip page loads: https://novatip.xyz/@alice renders 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/png returns a PNG

Environment Promotion

To promote from testnet to mainnet without rebuilding:

  1. Update STELLAR_NETWORK=mainnet in the backend env
  2. Update SOROBAN_RPC_URL and HORIZON_URL to mainnet endpoints
  3. Update TIP_SPLITTER_CONTRACT_ID to the mainnet contract ID
  4. Update USDC_CONTRACT_ID to the mainnet USDC SAC
  5. Set INDEXER_START_LEDGER to the current mainnet ledger sequence
  6. Restart the backend process
  7. Update NEXT_PUBLIC_STELLAR_NETWORK=mainnet and NEXT_PUBLIC_TIP_SPLITTER_CONTRACT_ID
  8. Redeploy the frontend