Ship Your Vibe-Coded App in 48 Hours: The Complete Deploy Playbook
You built something amazing with Cursor, Claude, or Bolt. It works on localhost. Now what? This is the definitive step-by-step guide to getting your vibe-coded app live on a real domain with SSL, a database, CI/CD, and monitoring — in a single weekend.
You Built Something. Now Ship It.
You spent the weekend vibe coding. Cursor was on fire. Claude nailed your API routes. Bolt scaffolded your entire frontend in 20 minutes. You're looking at your screen and thinking: this is actually good.
Then you try to show someone.
"Just go to localhost:3000!"
That's not how this works. And this is where 90% of vibe coders get stuck. Not because deploying is hard — but because nobody ever explained it to them in plain language, without assuming they already know what a reverse proxy is.
This guide fixes that. By the end, your app will be live on a real domain, with SSL, a production database, automatic deploys, and monitoring. You'll do it in 48 hours or less. No DevOps degree required.
Part 1: The "It Works on My Machine" Problem
Here's what's actually different between your laptop and production:
- Your local server dies when you close your laptop. Production servers run 24/7.
- localhost isn't accessible to anyone else. You need a public IP address and a domain.
- SQLite files live on your filesystem. One deploy wipes them.
- Your .env file has secrets in it. Push that to GitHub and bots will find your API keys within minutes. Literally minutes.
- No SSL means browsers show "Not Secure." Users bounce immediately.
The gap between "it runs" and "it's deployed" is not a coding problem. It's a checklist. And you're about to work through that checklist step by step.
Part 2: Choosing Your Hosting Platform
Not every platform is right for every project. Here's the honest breakdown:
Comparison Table
| Platform | Best For | Free Tier | Paid Starting | Deploy Speed | Database Built-in |
|---|---|---|---|---|---|
| Vercel | Next.js, React, static sites | Yes (generous) | $20/mo (Pro) | ~30 seconds | No (use Vercel Postgres or external) |
| Railway | Full-stack apps with backends | $5 free credit/mo | $5/mo | ~2 minutes | Yes (Postgres, MySQL, Redis) |
| DigitalOcean App Platform | Apps needing VPS control | No | $5/mo | ~3 minutes | Yes (managed Postgres from $15/mo) |
| Fly.io | APIs, edge deployment, global apps | Yes (limited) | ~$3/mo | ~2 minutes | Yes (Postgres, LiteFS) |
| Coolify | Self-hosted, full control, free | Yes (self-hosted) | $0 (your VPS cost) | ~3 minutes | Yes (anything you install) |
The Quick Decision Tree
Are you deploying a Next.js or React frontend? Use Vercel. It's literally built for this. Zero config. Push to GitHub, it deploys.
Do you have a backend with a database (Express, FastAPI, Django)? Use Railway. It gives you a database and a backend in one place. Connect with a URL. Done.
Do you want to learn real infrastructure? Use DigitalOcean or Fly.io. More control, slightly more setup.
Do you want to own everything and pay nothing for hosting? Use Coolify on a $5 VPS. It's a self-hosted alternative to Vercel/Netlify with a GUI.
For this guide, I'll show the two most common paths: Vercel (frontend) and Railway (backend + database). These cover 80% of what vibe coders are building.
Part 3: Getting Your Code Ready
Before you deploy anywhere, do these three things:
1. Make Sure Your Project Has a package.json (or Equivalent)
Every platform needs to know how to build your app. For a Node.js/Next.js project:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
}
For a Python backend:
# requirements.txt
fastapi==0.104.1
uvicorn==0.24.0
sqlalchemy==2.0.23
2. Add a .gitignore File
If you don't have one, create it now. This is non-negotiable:
# Dependencies
node_modules/
__pycache__/
venv/
# Environment variables — NEVER commit these
.env
.env.local
.env.production
# Build output
.next/
dist/
build/
# Database files
*.db
*.sqlite
# OS files
.DS_Store
Thumbs.db
# IDE
.vscode/
.idea/
3. Push to GitHub
If your code isn't on GitHub yet:
git init
git add .
git commit -m "Initial commit"
gh repo create my-app --public --push
Or if you prefer the manual route:
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/YOUR_USERNAME/your-app.git
git branch -M main
git push -u origin main
Part 4: Deploy to Vercel (Frontend)
This takes about 5 minutes.
Step 1: Connect Your Repo
- Go to vercel.com and sign in with GitHub
- Click "Add New Project"
- Select your repository
- Vercel auto-detects your framework (Next.js, Vite, etc.)
- Click Deploy
That's it. Your app is live at your-app.vercel.app.
Step 2: Add Environment Variables
If your app uses API keys, go to Settings → Environment Variables in the Vercel dashboard. Add each key:
NEXT_PUBLIC_API_URL=https://your-api.railway.app
DATABASE_URL=postgresql://...
OPENAI_API_KEY=sk-...
STRIPE_SECRET_KEY=sk_live_...
Important rules:
- Variables prefixed with
NEXT_PUBLIC_are exposed to the browser. Only use this for non-secret values. - Everything else stays server-side only.
- After adding variables, redeploy for them to take effect.
Step 3: Set Up Custom Domain
In the Vercel dashboard: Settings → Domains → Add
Type your domain (e.g., myapp.com). Vercel gives you DNS records to add:
Type: A
Name: @
Value: 76.76.21.21
Type: CNAME
Name: www
Value: cname.vercel-dns.com
Add these at your domain registrar (Namecheap, Cloudflare, etc.). SSL is automatic. Wait 5-10 minutes for propagation.
Part 5: Deploy to Railway (Backend + Database)
If your app has an API, a backend, or needs a persistent database, Railway is the fastest path.
Step 1: Create a Project
- Go to railway.app and sign in with GitHub
- Click "New Project"
- Choose "Deploy from GitHub repo"
- Select your backend repository
Step 2: Add a Database
In your Railway project, click "New" → "Database" → PostgreSQL.
Railway gives you a connection string automatically. Copy it — it looks like:
postgresql://postgres:AbCdEf123@containers-us-west-123.railway.app:5432/railway
Step 3: Connect Your App to the Database
Add the connection string as an environment variable in Railway:
- Click on your service
- Go to Variables tab
- Add:
DATABASE_URL= your connection string
In your code, reference it:
// Node.js with Prisma
// schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
# Python with SQLAlchemy
import os
DATABASE_URL = os.environ.get("DATABASE_URL")
engine = create_engine(DATABASE_URL)
Step 4: Run Migrations
Railway gives you a shell. Or use the Railway CLI:
npm install -g @railway/cli
railway login
railway link
railway run npx prisma migrate deploy
Step 5: Expose Your Service
By default, Railway services aren't public. Go to Settings → Networking → Generate Domain. You'll get something like your-app-production.up.railway.app.
Or add a custom domain the same way as Vercel — Railway gives you a CNAME record to add.
Part 6: Domain & DNS Setup (The Complete Version)
Buying a Domain
Two best options:
- Cloudflare Registrar (cloudflare.com) — At-cost pricing, free DNS, built-in DDoS protection. My top pick.
- Namecheap (namecheap.com) — Cheap, reliable, good UI.
A .com domain runs $8-12/year. Don't overthink the name. Ship first, rebrand later.
Pointing DNS (Cloudflare Example)
- Buy your domain on Cloudflare (or transfer nameservers to Cloudflare)
- Go to DNS → Records
- Add the records your hosting platform gave you
For Vercel:
Type: A | Name: @ | Content: 76.76.21.21 | Proxy: DNS only
Type: CNAME | Name: www | Content: cname.vercel-dns.com | Proxy: DNS only
For Railway:
Type: CNAME | Name: api | Content: your-app.up.railway.app | Proxy: DNS only
Pro tip: Turn off Cloudflare's proxy (orange cloud) for Vercel and Railway. They handle their own SSL. Double-proxying causes issues.
SSL Certificates
- Vercel: Automatic. Does it for you. Zero config.
- Railway: Automatic when you add a custom domain.
- DigitalOcean/VPS: Use Let's Encrypt with Certbot:
# Install Certbot on Ubuntu
sudo apt update
sudo apt install certbot python3-certbot-nginx
# Get a certificate
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
# Auto-renewal is set up automatically. Verify with:
sudo certbot renew --dry-run
Part 7: Environment Variables & Secrets
This deserves its own section because getting it wrong can cost you real money.
The Rules
- NEVER commit
.envto git. Add it to.gitignoreimmediately. - NEVER hardcode API keys in your source code. Not even "temporarily."
- NEVER paste secrets in Slack, Discord, or email. Use a password manager or 1Password.
- Rotate keys immediately if you accidentally push them to GitHub.
How to Check if You Already Leaked Secrets
# Search your git history for common secret patterns
git log -p | grep -i "sk-\|api_key\|secret\|password\|token" | head -20
If you find anything, those keys are compromised. Go rotate them now.
Setting Environment Variables by Platform
Vercel: Dashboard → Project → Settings → Environment Variables. Can set different values for Production, Preview, and Development.
Railway:
Dashboard → Service → Variables tab. Click "New Variable" or bulk import from a .env file (Railway strips it after import, nothing gets committed).
Fly.io:
fly secrets set DATABASE_URL="postgresql://..." OPENAI_API_KEY="sk-..."
DigitalOcean App Platform: Dashboard → App → Settings → App-Level Environment Variables.
Local Development:
Create a .env.local file (auto-ignored by most frameworks):
# .env.local — this file stays on your machine ONLY
DATABASE_URL=postgresql://localhost:5432/myapp
OPENAI_API_KEY=sk-dev-key-here
STRIPE_SECRET_KEY=sk_test_...
Part 8: Database in Production
Why SQLite Doesn't Work in Production (Usually)
SQLite stores everything in a single file. On platforms like Vercel or Railway:
- The filesystem is ephemeral. Your data gets wiped on every deploy.
- No concurrent writes. Two users hitting your API simultaneously can lock the database.
- No remote access. You can't query your production database from your laptop.
SQLite is fine for read-heavy apps on a single server (blogs, documentation). For everything else, use a real database.
Your Options
| Database | Best For | Free Tier | Managed By |
|---|---|---|---|
| Supabase | Full Postgres + auth + realtime | 500MB, 2 projects | Supabase |
| Neon | Serverless Postgres, scales to zero | 512MB | Neon |
| PlanetScale | MySQL, branching workflow | Deprecated free tier | PlanetScale |
| Turso | Edge SQLite (libSQL), very fast reads | 9GB, 500M rows | Turso |
| Railway Postgres | Simple Postgres alongside your app | $5 credit/mo | Railway |
My Recommendation
If you're using Prisma: go with Neon or Railway Postgres. Both work out of the box with Prisma's connection string.
If you want auth + database together: go with Supabase. It gives you Postgres, authentication, and a REST API in one service.
If you're deploying to the edge (Cloudflare Workers, Fly.io): use Turso. It's SQLite-compatible but distributed globally.
Migration Strategy
Moving from SQLite to Postgres is not as scary as it sounds.
If you're using Prisma:
# 1. Update your schema.prisma
# Change provider from "sqlite" to "postgresql"
# 2. Set your new DATABASE_URL
# 3. Push the schema
npx prisma db push
# 4. If you need to migrate data, use Prisma's migrate
npx prisma migrate dev --name switch-to-postgres
If you're using raw SQL, the main changes are:
INTEGER PRIMARY KEY AUTOINCREMENT→SERIAL PRIMARY KEYTEXTstaysTEXT(or useVARCHAR)DATETIME→TIMESTAMP- Boolean
0/1→ nativeBOOLEAN
Part 9: CI/CD for Beginners
CI/CD means your app deploys automatically when you push code. No manual steps. No FTP. No SSH-ing into a server.
If You're on Vercel or Railway
Good news: you already have CI/CD. Both platforms deploy automatically when you push to your main branch on GitHub. There's nothing to set up.
If You Want More Control: GitHub Actions
GitHub Actions lets you run tests, lint code, build, and deploy — all triggered by a git push.
Here's a real, working workflow file. Create this at .github/workflows/deploy.yml:
name: Build and Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Run tests
run: npm test
- name: Build
run: npm run build
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
Adding Secrets to GitHub Actions
- Go to your repo on GitHub
- Settings → Secrets and variables → Actions
- Click "New repository secret"
- Add each secret (DATABASE_URL, API keys, etc.)
These secrets are encrypted and only available during workflow runs. They never appear in logs.
A More Advanced Workflow: Deploy to DigitalOcean
If you're deploying to a VPS and want full control:
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Deploy via SSH
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /var/www/myapp
git pull origin main
npm ci --production
npm run build
pm2 restart myapp
This SSHes into your server, pulls the latest code, rebuilds, and restarts the process manager. Simple and reliable.
Part 10: Monitoring — "Is It Still Running?"
You deployed. It's live. Now you need to know when it breaks — before your users tell you.
Free Uptime Monitoring: UptimeRobot
- Go to uptimerobot.com (free for 50 monitors)
- Add a new HTTP(s) Monitor
- Set the URL to your production app (e.g.,
https://myapp.com) - Set check interval to 5 minutes
- Add your email for alerts
That's it. You'll get an email the moment your site goes down, and another when it comes back up.
Add a Health Check Endpoint
Create a simple endpoint your monitoring can ping:
// Next.js: app/api/health/route.ts
import { NextResponse } from "next/server";
export async function GET() {
return NextResponse.json({
status: "ok",
timestamp: new Date().toISOString(),
uptime: process.uptime(),
});
}
# FastAPI
@app.get("/health")
def health_check():
return {"status": "ok", "timestamp": datetime.utcnow().isoformat()}
Point UptimeRobot at /api/health instead of your homepage. It's faster and more reliable for monitoring.
Error Tracking: Sentry
Free tier covers 5,000 errors/month. That's plenty for most apps.
npm install @sentry/nextjs
npx @sentry/wizard@latest -i nextjs
This sets up Sentry automatically. It captures:
- Unhandled exceptions
- API errors
- Performance metrics
- User session replay (on paid plans)
The wizard creates sentry.client.config.ts, sentry.server.config.ts, and sentry.edge.config.ts. Add your DSN as an environment variable:
SENTRY_DSN=https://abc123@o123456.ingest.sentry.io/789
Basic Logging
At minimum, log important events in your app:
// Simple structured logging
function log(level, message, data = {}) {
console.log(JSON.stringify({
level,
message,
timestamp: new Date().toISOString(),
...data,
}));
}
// Usage
log("info", "User signed up", { userId: "123", plan: "free" });
log("error", "Payment failed", { userId: "123", error: err.message });
On Vercel, these logs appear in Deployments → Functions → Logs. On Railway, they're in the Deployments tab for your service.
Part 11: The Launch Checklist
Before you share the link, run through every item. No exceptions.
Performance & Basics
- Run Lighthouse audit — open Chrome DevTools → Lighthouse → Generate Report. Aim for 90+ on Performance and Accessibility.
- Test on mobile — not just "responsive mode" in your browser. Open it on an actual phone.
- Test on slow connection — Chrome DevTools → Network → Throttle to "Slow 3G". Does it still work?
- Check all links — every button, every navigation item. Click them all.
- Test forms — submit every form with valid and invalid data. Check error states.
SEO & Social
- Add a page title and meta description to every page:
<head>
<title>MyApp — Solve [Problem] in Minutes</title>
<meta name="description" content="A clear, compelling description under 160 characters." />
</head>
- Add Open Graph tags for social sharing:
<meta property="og:title" content="MyApp" />
<meta property="og:description" content="What your app does in one sentence." />
<meta property="og:image" content="https://myapp.com/og-image.png" />
<meta property="og:url" content="https://myapp.com" />
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary_large_image" />
- Create an OG image — 1200x630px. Use og-playground.vercel.app to generate one.
- Add a
robots.txtin your public folder:
User-agent: *
Allow: /
Sitemap: https://myapp.com/sitemap.xml
- Add a
sitemap.xml— for Next.js, use the built-inapp/sitemap.ts:
// app/sitemap.ts
import { MetadataRoute } from "next";
export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: "https://myapp.com",
lastModified: new Date(),
changeFrequency: "weekly",
priority: 1,
},
{
url: "https://myapp.com/pricing",
lastModified: new Date(),
changeFrequency: "monthly",
priority: 0.8,
},
];
}
Analytics & Tracking
- Set up analytics — Plausible (privacy-friendly, $9/mo), Umami (self-hosted, free), or Google Analytics (free, less private).
- Add a favicon — put
favicon.icoin yourpublic/folder. Use favicon.io to generate from text or an image. - Verify your domain in Google Search Console at search.google.com/search-console. Submit your sitemap.
Security
- All environment variables are set in your hosting platform. Not hardcoded.
-
.envis in.gitignore. Verify:git statusshould NOT show your.envfile. - HTTPS is working — visit your site with
https://and verify the lock icon appears.
The 48-Hour Timeline
Here's how this breaks down if you're starting from zero:
Saturday Morning (Hours 1-4)
- Push code to GitHub
- Deploy frontend to Vercel
- Deploy backend to Railway (if needed)
- Connect database
Saturday Afternoon (Hours 5-8)
- Buy domain on Cloudflare
- Point DNS to Vercel/Railway
- Set up environment variables
- Test everything on the live URL
Sunday Morning (Hours 9-12)
- Add meta tags, OG image, sitemap
- Run Lighthouse audit, fix issues
- Set up UptimeRobot monitoring
- Set up Sentry error tracking
Sunday Afternoon (Hours 13-16)
- Test on mobile devices
- Test all forms and user flows
- Set up Google Search Console
- Share the link
You're live.
Common Mistakes (And How to Fix Them)
"My environment variables aren't working" On Vercel, you need to redeploy after adding variables. Click the three dots on your latest deployment → Redeploy.
"My API calls fail in production but work locally"
You're probably hitting http://localhost:3001 instead of your production API URL. Check your NEXT_PUBLIC_API_URL environment variable.
"My database is empty after deploy"
You need to run migrations in production. Use railway run npx prisma migrate deploy or add it to your build command.
"My images aren't loading"
If you're using Next.js <Image>, add your image domains to next.config.js:
// next.config.js
module.exports = {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "your-image-host.com",
},
],
},
};
"I accidentally pushed my .env file"
- Add
.envto.gitignore - Remove it from git tracking:
git rm --cached .env - Commit the removal
- Go rotate every single key in that file immediately
What Comes After Deploy
Shipping is the beginning, not the end. Once your app is live:
- Set up a feedback channel. A simple form, a Discord, or even a mailto link. You need to hear from users.
- Watch your error logs. Check Sentry daily for the first week.
- Monitor performance. If your Lighthouse score drops, investigate.
- Ship updates fast. With CI/CD set up, pushing a fix is just
git push. Use that speed. - Tell people about it. Post on Twitter/X, Reddit, Hacker News, Product Hunt. The best app nobody knows about is a dead app.
The gap between a vibe coder and a real builder isn't talent. It's deployment. You just closed that gap.
Stop vibing. Start shipping.
Frequently Asked Questions
Do I need to know DevOps to deploy my app?
How much does it cost to deploy a vibe-coded app?
Should I use Vercel or Railway?
Is SQLite okay for production?
What if I accidentally pushed my .env file to GitHub?
How do I get a free SSL certificate?
Comments
Loading comments...
Published March 19, 2026
Building businesses with automation and AI. Sharing workflows, templates, and real strategies that work.
Related content
Building Your Automation Stack from Zero
A step-by-step roadmap to go from manual everything to a fully automated business operation.
guideWeb Scraping for Lead Gen: A Practical Guide
Extract business data from any website legally and ethically to build your prospect lists.
guideEmail Automation That Actually Works
Stop sending generic emails. Build smart email sequences that adapt based on recipient behavior.
guide