Vercel Deployment
Deploying to Vercel
Run your Rails app on Vercel’s Edge Network with serverless databases.
Table of Contents
Overview
Vercel deployment runs your application as serverless functions with global distribution. Requests hit the nearest edge location for low latency.
Use cases:
- Global applications needing low latency
- Pay-per-request pricing
- Automatic scaling
- Integration with Vercel’s platform features
Prerequisites
- Vercel CLI
npm i -g vercel vercel login - Link project
cd your-rails-app vercel # First run links the project - Create database — Choose one:
- Neon — Serverless PostgreSQL
- Turso — SQLite at the edge
- PlanetScale — Serverless MySQL
- Connect database
- Add
DATABASE_URLto Vercel Environment Variables - Copy to
.env.localfor local migrations
- Add
Database Options
| Adapter | Service | Protocol | Best For |
|---|---|---|---|
neon |
Neon | HTTP | PostgreSQL compatibility |
turso |
Turso | HTTP | SQLite, edge replication |
planetscale |
PlanetScale | HTTP | MySQL, branching workflow |
All use HTTP protocols that work in edge environments (no TCP sockets).
Deployment
# Run migrations first
bin/juntos migrate -t vercel -d neon
# Deploy
bin/juntos deploy -t vercel -d neon
The deploy command:
- Builds the app with Vercel configuration
- Generates
vercel.jsonandapi/[[...path]].js - Verifies the build loads correctly
- Runs
vercel --prod
Manual Deployment
If you prefer manual control:
# Build only
bin/juntos build -t vercel -d neon
# Deploy with Vercel CLI
cd dist
vercel --prod
Generated Files
vercel.json
{
"version": 2,
"buildCommand": "npm run build",
"outputDirectory": "dist",
"routes": [
{ "src": "/app/assets/(.*)", "dest": "/app/assets/$1" },
{ "src": "/(.*)", "dest": "/api/[[...path]]" }
]
}
api/[[…path]].js
import { Application, Router } from '../lib/rails.js';
import '../config/routes.js';
import { migrations } from '../db/migrate/index.js';
import { Seeds } from '../db/seeds.js';
import { layout } from '../app/views/layouts/application.js';
Application.configure({
migrations: migrations,
seeds: Seeds,
layout: layout
});
export default Application.handler();
export const config = {
runtime: 'edge'
};
Environment Variables
Set these in Vercel Dashboard → Settings → Environment Variables:
| Variable | Description | Example |
|---|---|---|
DATABASE_URL |
Neon connection string | postgres://user:pass@host/db |
TURSO_DATABASE_URL |
Turso database URL | libsql://db-org.turso.io |
TURSO_AUTH_TOKEN |
Turso auth token | eyJ... |
For local development, copy to .env.local:
# .env.local
DATABASE_URL=postgres://user:pass@host/db
Edge vs Node Runtime
Juntos defaults to Edge runtime for Vercel. For Node.js runtime:
bin/juntos deploy -t vercel-node -d neon
Edge runtime:
- Faster cold starts (~50ms)
- Global distribution
- Limited Node.js APIs
- HTTP-only database connections
Node.js runtime:
- Full Node.js APIs
- TCP database connections possible
- Longer cold starts (~250ms)
- Fewer geographic locations
Troubleshooting
“Module not found” errors
# Clear cache and redeploy
bin/juntos deploy -t vercel -d neon --force
Database connection errors
- Verify
DATABASE_URLis set in Vercel - Check database is accessible from Vercel’s IPs
- Ensure SSL mode is correct for your database
Timeout errors
Edge functions have a 30-second limit. For long operations:
- Use background jobs (Inngest, Trigger.dev)
- Stream responses
- Break into smaller operations
Limitations
- No filesystem writes — Use object storage (Vercel Blob, S3)
- No WebSockets — Use Pusher, Ably, or similar
- 30-second timeout — Long operations need different architecture
- Cold starts — First request after idle may be slower
Static Assets
Static assets in app/assets/ are served directly by Vercel’s CDN. The route configuration handles this:
{ "src": "/app/assets/(.*)", "dest": "/app/assets/$1" }
For Tailwind CSS, the build process generates app/assets/builds/tailwind.css.