Use this checklist before every production launch or major deployment. Work through the sections in order — later sections depend on earlier ones.
- Oracle Cloud VM provisioned (or GCP/AWS equivalent) — Ubuntu 22.04+, minimum 2 vCPU / 4 GB RAM
- Docker and Docker Compose installed on VM (
sudo apt install -y docker.io docker-compose-plugin) - VM user added to docker group (
sudo usermod -aG docker $USER) - SSH key pair generated; public key added to
~/.ssh/authorized_keyson the VM - Private SSH key saved as
SSH_PRIVATE_KEYGitHub Secret (see section below) - Domain registered and DNS A record pointing to VM public IP
- DuckDNS or similar dynamic DNS configured if using a dynamic IP (
API_DOMAIN=api.yourdomain.com) - Ports 80 and 443 open in VM firewall / security group
- VM has outbound access to Binance API endpoints
Set all of the following in the NetTrader GitHub repo → Settings → Secrets and variables → Actions.
-
HOST— VM public IP address -
SSH_PRIVATE_KEY— SSH private key matching the public key on the VM -
GH_TOKEN— GitHub Personal Access Token (if needed for deployment) -
DBCONNECTIONSTRING— PostgreSQL connection string Example:Host=localhost;Database=nettrader;Username=postgres;Password=strongpassword -
JWT_SECRET— Minimum 32-character random string Generate:openssl rand -base64 32 -
ENCRYPTION_KEY— 32-byte Base64-encoded key for field-level encryption Generate:openssl rand -base64 32 -
ADMIN_USERNAME— Admin user email address -
ADMIN_PASSWORD_HASH— BCrypt hash of the admin password Generate with the app'sHashPasswordutility method -
BINANCE_API_KEY— Binance Futures API key (Futures trading permission; no withdrawal permission) -
BINANCE_API_SECRET— Binance Futures API secret -
TELEGRAM_BOT_TOKEN— Telegram bot token from @BotFather -
TELEGRAM_CHAT_ID— Your Telegram chat ID (send/startto the bot to get it) -
GEMINI_API_KEY— Google AI Studio API key for Gemini -
SMTP_HOST— SMTP server hostname (e.g.smtp.gmail.com) -
SMTP_USERNAME— SMTP login email address -
SMTP_PASSWORD— SMTP password or Gmail App Password -
SMTP_FROMEMAIL— From address for outgoing emails (e.g.noreply@nettrader.app) -
GOOGLE_AUTH_CLIENTID— Google OAuth 2.0 Client ID (must also be set in frontend) -
STRIPE_SECRETKEY— Stripe secret key (sk_live_...for production) -
STRIPE_WEBHOOKSECRET— Stripe webhook signing secret (whsec_...)
- GitHub repo connected to a new Vercel project (Framework: Next.js)
- Environment variables set in Vercel project → Settings → Environment Variables:
-
OPENAI_API_KEY— OpenAI API key (for GPT-4o-mini, Whisper, TTS) -
NEXT_PUBLIC_SUPABASE_URL— Supabase project URL -
SUPABASE_SERVICE_ROLE_KEY— Supabase service role key (keep secret, server-only) -
UPSTASH_REDIS_REST_URL— Upstash Redis REST endpoint URL -
UPSTASH_REDIS_REST_TOKEN— Upstash Redis REST token -
ALLOWED_ORIGIN— Frontend domain (e.g.https://your-frontend.vercel.app)
-
- Production deployment triggered and URL noted (e.g.
https://nettrader-serverless.vercel.app) - Custom domain configured (optional)
- Supabase migration run:
supabase/migrations/001_create_chat_messages.sql - Supabase storage bucket
audio_responsescreated and set to public
- GitHub repo connected to a new Vercel project (Framework: Next.js)
- Environment variables set in Vercel project → Settings → Environment Variables:
-
NEXT_PUBLIC_API_URL— Backend URL (e.g.https://api.yourdomain.com) -
NEXT_PUBLIC_SITE_URL— Frontend URL (e.g.https://your-frontend.vercel.app) -
NEXT_PUBLIC_GOOGLE_CLIENT_ID— Google OAuth Client ID (same value asGOOGLE_AUTH_CLIENTIDin backend) -
NEXT_PUBLIC_SERVERLESS_URL— NetTraderServerless Vercel deployment URL -
NEXT_PUBLIC_SUPABASE_URL— Supabase project URL -
NEXT_PUBLIC_SUPABASE_ANON_KEY— Supabase public anon key
-
- Production deployment triggered
- Custom domain configured
-
NEXT_PUBLIC_MOCKis not set (or explicitly set tofalse) in production
- Google Cloud Console project created (or existing project reused)
- APIs & Services → Credentials → Create OAuth 2.0 Client ID (Web application type)
- Authorized JavaScript origins added:
https://your-frontend-domain.comhttp://localhost:3000(for local development)
- Authorized redirect URIs configured (if needed by your flow)
- Client ID copied to:
-
GOOGLE_AUTH_CLIENTIDGitHub Secret (backend) -
NEXT_PUBLIC_GOOGLE_CLIENT_IDVercel env var (frontend)
-
- Stripe account created and verified
- Products and prices created in Stripe Dashboard (note the price IDs)
- Price IDs updated in the frontend pricing page
- Webhook endpoint registered in Stripe Dashboard:
URL:
https://your-api-domain/api/payments/webhook - Webhook events configured:
-
checkout.session.completed -
customer.subscription.deleted -
invoice.payment_failed
-
-
STRIPE_SECRETKEYset in GitHub Secrets -
STRIPE_WEBHOOKSECRETset in GitHub Secrets - End-to-end test completed with Stripe test card (
4242 4242 4242 4242)
- Project created at supabase.com
- Migration run:
supabase/migrations/001_create_chat_messages.sql(via SQL Editor orsupabase db push) - Storage bucket
audio_responsescreated and set to public - Project URL and anon key copied to frontend Vercel env vars (
NEXT_PUBLIC_SUPABASE_URL,NEXT_PUBLIC_SUPABASE_ANON_KEY) - Service role key copied to serverless Vercel env var (
SUPABASE_SERVICE_ROLE_KEY)
- Gmail App Password created (Google Account → Security → 2-Step Verification → App passwords), or SendGrid / Mailgun account configured
- All four SMTP secrets added to GitHub Secrets (
SMTP_HOST,SMTP_USERNAME,SMTP_PASSWORD,SMTP_FROMEMAIL) - End-to-end test: call
POST /api/auth/register/request-codewith a real email and verify the OTP arrives
- Bot created via @BotFather (
/newbot) - Bot token saved as
TELEGRAM_BOT_TOKENGitHub Secret - Start a conversation with the bot (send any message)
- Chat ID retrieved (call
https://api.telegram.org/bot<TOKEN>/getUpdates) and saved asTELEGRAM_CHAT_ID - After first deployment, test commands:
/status,/pause,/resume,/help
- Binance Futures account funded with sufficient margin
- API key created with Futures trading permission only — withdrawal permission must be disabled
- IP whitelist configured to the VM's public IP address
- Keys saved to
BINANCE_API_KEYandBINANCE_API_SECRETGitHub Secrets - Testnet run completed before switching to mainnet keys
- Backend health check passes:
GET https://your-api-domain/healthreturns200 - OTP email registration flow works end-to-end (request code → confirm → receive JWT)
- Google login flow works (frontend → backend
/api/auth/google→ tokens) - Dashboard loads with real bot data (no mock mode)
- SignalR connection established (green indicator in dashboard header)
- Bot can be paused and resumed from the dashboard
- OpenClaw chat widget works: frontend → NetTraderServerless → OpenAI response
- Voice input and TTS audio response work in the chat widget
- Position open/close cycle tested on Binance testnet with small size
- Stripe checkout flow tested with test card
4242 4242 4242 4242 - Stripe webhook receives and processes
checkout.session.completed - No error logs in
docker compose logs apiafter 10 minutes of running
- Landing page copywriting finalized (hero, features, pricing, FAQ)
- Pricing page live with correct Stripe product IDs and live-mode prices
- Privacy Policy page live (required by Google OAuth and Stripe)
- Terms of Service page live
- Waitlist / early access signup flow tested end-to-end
- Social media accounts created (@NetTraderAI or similar handle)
- Demo video recorded (dashboard overview, chat with OpenClaw, live trade)
- Product Hunt launch page prepared (tagline, description, media assets)
- First blog post or content piece about the AI/ML trading approach written
- Tracking / analytics set up (Plausible, Umami, or similar)