This recipe deploys a full-stack MVP to production with CI/CD pipelines, environment variable management, error tracking, and uptime monitoring — covering five platforms (Vercel, Railway, Fly.io, AWS Amplify, Render) with platform-specific setup instructions, cost benchmarks, and monitoring integration. The output is a live application with automated deployments on every Git push, proper secret management, error alerting, and uptime monitoring. [src1]
Which path?
├── Frontend-only MVP (Next.js, Astro, React SPA)
│ ├── budget = free → PATH A: Vercel Hobby (non-commercial)
│ └── budget > $0 → PATH B: Vercel Pro ($20/mo)
├── Full-stack MVP (frontend + API + database)
│ ├── budget < $10/mo → PATH C: Railway Hobby ($5/mo + usage)
│ ├── budget $10-50/mo → PATH D: Railway Pro ($20/mo) or Render ($7-25/mo)
│ └── budget > $50/mo → PATH E: Fly.io or AWS Amplify
├── API/backend only (no frontend)
│ ├── budget < $10/mo → PATH C: Railway Hobby
│ └── budget > $10/mo → PATH D: Railway Pro or Fly.io
└── Already in AWS ecosystem
└── PATH F: AWS Amplify (leverage existing credits/services)
| Path | Tools | Cost/mo | CI/CD | Best For |
|---|---|---|---|---|
| A: Vercel Hobby | Vercel + Supabase | $0 | Git push auto-deploy | Non-commercial frontend MVPs |
| B: Vercel Pro | Vercel + Supabase/Neon | $20+ | Git push + preview deploys | Commercial Next.js MVPs |
| C: Railway Hobby | Railway (app + DB) | $5-15 | Git push auto-deploy | Side projects, early MVPs |
| D: Railway Pro / Render | Railway or Render | $20-50 | Git push + staging envs | Production MVPs with databases |
| E: Fly.io | Fly.io + managed DB | $20-80 | flyctl deploy + GH Actions | Global low-latency apps |
| F: AWS Amplify | Amplify + RDS/DynamoDB | $0-50 (credits) | Amplify CI/CD pipeline | AWS-centric teams |
Duration: 10-15 minutes · Tool: Deployment platform dashboard or CLI
Connect your Git repository to the deployment platform. Each platform auto-detects frameworks and configures build settings.
Vercel (frontend or Next.js full-stack):
# Dashboard: New Project → Import Git Repository → select repo
# CLI alternative:
npm i -g vercel
cd your-mvp-project
vercel --prod
Railway (full-stack with database):
# Dashboard: New Project → Deploy from GitHub repo
# CLI alternative:
npm i -g @railway/cli
railway login
railway init
railway up
# Add database:
railway add --database postgres
# Connection string auto-injected as DATABASE_URL
Fly.io (global edge deployment):
curl -L https://fly.io/install.sh | sh
fly auth login
fly launch # Follow prompts
fly deploy
# Add PostgreSQL:
fly postgres create --name your-app-db
fly postgres attach your-app-db
Verify: Application loads at the platform-provided subdomain (e.g., your-app.vercel.app, your-app.up.railway.app, your-app.fly.dev). [src1] [src2] · If failed: Check build logs. Common causes: missing build command, wrong output directory, Node.js version mismatch.
Duration: 5-10 minutes · Tool: Platform dashboard or CLI
Store all secrets as platform environment variables. Never commit secrets to Git.
# Vercel
vercel env add DATABASE_URL production
vercel env pull .env.local # For local dev
# Railway
railway variables set DATABASE_URL="postgresql://..."
# Fly.io (encrypted, values hidden after setting)
fly secrets set DATABASE_URL="postgresql://..."
# AWS Amplify: App settings → Environment variables
Verify: Application starts with all env vars loaded. Check logs for "undefined" errors. · If failed: Variable names are case-sensitive. Redeploy after adding variables.
Duration: 10-15 minutes · Tool: Platform settings + GitHub Actions
All platforms include auto-deploy on push. Add testing and quality gates with GitHub Actions.
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npm test
Vercel creates preview deployments automatically for every PR. Railway and Render support staging environments via branch-based deployments.
Verify: Push a commit — CI tests run, preview deployment created, merge to main triggers production deploy. [src1] [src5] · If failed: Check GitHub Actions logs. Verify platform webhook is connected.
Duration: 10-15 minutes · Tool: Sentry + BetterStack/UptimeRobot
# Install Sentry SDK
npm install @sentry/node @sentry/profiling-node
# For Next.js (wizard auto-configures):
npx @sentry/wizard@latest -i nextjs
Add a health check endpoint at /api/health that verifies database connectivity and returns JSON status.
Set up uptime monitoring: BetterStack (free: 10 monitors, 3-min intervals) or UptimeRobot (free: 50 monitors, 5-min intervals).
Verify: Trigger a test error in Sentry — appears in dashboard within 30 seconds. Uptime monitor shows "UP". · If failed: Check Sentry DSN env var. Verify monitor URL is externally accessible.
Duration: 5-15 minutes · Tool: Platform dashboard + DNS registrar
# Vercel: vercel domains add yourdomain.com
# Railway: Dashboard → Settings → Domains → Add
# Fly.io: fly certs create yourdomain.com
# Render: Dashboard → Settings → Custom Domains
# DNS records at registrar:
# A @ [platform IP]
# CNAME www [platform target]
Verify: https://yourdomain.com loads with valid SSL. HTTP redirects to HTTPS. · If failed: DNS propagation takes up to 48 hours. Check with dnschecker.org.
Duration: 10 minutes · Tool: Platform-native logs or external service
All platforms provide built-in log viewers. For advanced needs, configure log drains to Datadog, Axiom, or BetterStack.
# Vercel: vercel integrations add datadog
# Railway: Dashboard → Service → Logs (built-in)
# Fly.io: fly logs (or fly logs --json for parsing)
Verify: Generate requests and confirm log entries appear within 60 seconds. · If failed: Ensure app outputs to stdout/stderr, not file-based logging.
{
"output_type": "deployed_mvp_infrastructure",
"format": "live URL + CI/CD pipeline + monitoring",
"columns": [
{"name": "production_url", "type": "string", "description": "Custom domain or platform subdomain", "required": true},
{"name": "platform", "type": "string", "description": "Hosting platform used", "required": true},
{"name": "cicd_status", "type": "string", "description": "CI/CD pipeline status", "required": true},
{"name": "preview_url_pattern", "type": "string", "description": "URL pattern for preview deployments", "required": false},
{"name": "sentry_dsn", "type": "string", "description": "Sentry DSN for error tracking", "required": false},
{"name": "uptime_monitor_url", "type": "string", "description": "Uptime monitoring dashboard URL", "required": false},
{"name": "monthly_cost", "type": "number", "description": "Monthly infrastructure cost in USD", "required": true},
{"name": "ssl_status", "type": "string", "description": "SSL certificate status", "required": true}
],
"expected_row_count": "1",
"sort_order": "N/A",
"deduplication_key": "production_url"
}
| Quality Metric | Minimum Acceptable | Good | Excellent |
|---|---|---|---|
| Deploy time (push to live) | < 10 minutes | < 3 minutes | < 1 minute |
| Preview deployments | None | Per PR | Per PR with seeded test data |
| Error tracking | None | Sentry captures errors | Sentry + performance monitoring |
| Uptime monitoring | None | 5-min check interval | 1-min check + status page |
| SSL certificate | Valid, no warnings | A rating on ssllabs.com | A+ rating |
| Health check endpoint | None | Returns 200 OK | Checks DB + external deps |
| Rollback capability | Redeploy old commit | 1-click rollback | Auto-rollback on health failure |
If below minimum: Focus on CI/CD pipeline first, then add monitoring. A working deploy pipeline with tests is more valuable than monitoring a broken process.
| Error | Likely Cause | Recovery Action |
|---|---|---|
| "Module not found" build failure | Missing dependency in package.json | Run npm install {module}, commit lockfile, redeploy |
| Node.js version mismatch | Platform default differs from local | Add "engines": {"node": ">=20"} to package.json |
| Deploy timeout | App fails to start or build too long | Check for missing env vars, increase timeout, verify start command |
| 502 Bad Gateway | App crashed on startup | Check runtime logs — usually missing env vars or failed DB connection |
| Database connection refused | Wrong connection string or firewall | Verify DATABASE_URL, check platform IP allowlists, enable connection pooling |
| "Too many connections" | Serverless functions opening new connections per request | Implement connection pooling: Supabase pooler, PgBouncer, or Prisma Accelerate |
| Rate limit 429 | Platform or API limit exceeded | Add caching layer, implement throttling, or upgrade plan |
| Component | Free Tier | Startup ($20-50/mo) | Growth ($50-200/mo) |
|---|---|---|---|
| Vercel hosting | Hobby: $0 (non-commercial) | Pro: $20/user/mo | Pro + usage overage |
| Railway hosting | N/A (no free tier) | Hobby: $5 + usage (~$10-20) | Pro: $20 + usage (~$30-80) |
| Fly.io hosting | N/A (no free tier) | ~$5-15/mo (shared CPU) | ~$20-60/mo (dedicated CPU) |
| AWS Amplify | Free tier ($200 credit) | ~$5-20/mo after credits | ~$20-80/mo |
| Render hosting | Free: 750 hrs/mo | Starter: $7/service | Standard: $25/service |
| Managed database | Supabase/Neon free | Supabase Pro: $25/mo | Railway PG: $10-30/mo |
| Error tracking | Sentry free: 5K errors | Sentry Team: $26/mo | Sentry Business: $80/mo |
| Uptime monitoring | UptimeRobot free | BetterStack: $10/mo | Checkly: $30/mo |
| Total | $0 | $20-60/mo | $80-250/mo |
Committing API keys, database URLs, or secrets directly in source code. Even private repos can leak — credentials in Git history persist forever even after file deletion. [src1]
Store all secrets as platform environment variables. Use .env.local for development only with .gitignore protection. Audit with git log --all -S "sk_live".
Deploying an MVP and only discovering downtime when users complain. Without monitoring, silent failures go undetected for hours. [src6]
Add /api/health that checks database connectivity. Configure UptimeRobot or BetterStack (both free) to ping every 5 minutes with Slack/email alerts.
A misconfigured migration or accidental deletion in development destroys production data.
Use separate database instances for dev, staging, and production. Railway and Render auto-create per-environment databases.
Use this recipe when the agent needs to take a working MVP codebase from local development to a production deployment with CI/CD, environment management, and monitoring. Requires the application code to exist and work locally. This recipe handles infrastructure, not application development.