Self-Hosting
Deploy Schemaful to your own infrastructure.
Requirements
- • Node.js 22+ (or Docker)
- • PostgreSQL 14+ database
- • 512MB RAM minimum (1GB recommended)
Docker Deployment
The easiest way to deploy Schemaful is with Docker.
Docker Compose
docker-compose.yml
version: "3.8"
services:
schemaful:
image: schemaful/cms:latest
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://postgres:password@db:5432/schemaful
- NODE_ENV=production
depends_on:
- db
db:
image: postgres:16-alpine
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
- POSTGRES_DB=schemaful
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:Run
docker-compose up -dAccess Schemaful at http://localhost:3000
Vercel Deployment
Deploy to Vercel with a managed PostgreSQL database (Neon recommended).
1. Create Neon Database
Sign up at neon.tech and create a new project. Copy the connection string.
2. Deploy to Vercel
# Clone and deploy
npx create-schemaful@latest my-cms
cd my-cms
vercel3. Add Environment Variables
In Vercel dashboard, add DATABASE_URL with your Neon connection string.
Railway Deployment
Railway provides automatic PostgreSQL provisioning.
# Install Railway CLI
npm install -g @railway/cli
# Login and deploy
railway login
railway init
railway add --plugin postgresql
railway upRailway automatically sets DATABASE_URL.
Manual Node.js
Deploy on any server with Node.js.
# Clone repository
git clone https://github.com/schemaful/schemaful
cd schemaful
# Install dependencies
pnpm install
# Build
pnpm build
# Set environment variables
export DATABASE_URL="postgresql://..."
export NODE_ENV="production"
# Run migrations
pnpm db:push
# Start server
pnpm startEnvironment Variables
| Variable | Required | Description |
|---|---|---|
| DATABASE_URL | Yes | PostgreSQL connection string |
| NODE_ENV | No | Environment (production, development) |
| SESSION_SECRET | Yes* | Secret for session encryption (auto-generated in dev) |
| ASSET_UPLOAD_URL | No | S3-compatible upload endpoint |
| ASSET_PUBLIC_URL | No | CDN URL for serving assets |
Database Setup
Schemaful uses Drizzle ORM for database management.
Initialize Tables
# Push schema to database (creates tables)
pnpm db:push
# Or generate and run migrations
pnpm db:generate
pnpm db:migrateDatabase Tables
- •
cms_locales— Language definitions - •
cms_schemas— Content type definitions - •
cms_fields— Field configurations - •
cms_entries— Content data (JSONB) - •
cms_assets— Media metadata - •
cms_users— User accounts - •
cms_sessions— Active sessions
Asset Storage
By default, assets are stored locally. For production, configure S3-compatible storage:
.env
# Cloudflare R2 (recommended)
ASSET_UPLOAD_URL=https://account.r2.cloudflarestorage.com/bucket
ASSET_PUBLIC_URL=https://cdn.yourdomain.com
R2_ACCESS_KEY_ID=your-key
R2_SECRET_ACCESS_KEY=your-secret
# AWS S3
ASSET_UPLOAD_URL=https://s3.amazonaws.com/bucket
ASSET_PUBLIC_URL=https://bucket.s3.amazonaws.comReverse Proxy
Example Nginx configuration:
nginx.conf
server {
listen 80;
server_name cms.yourdomain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_bypass $http_upgrade;
}
}Health Check
Schemaful exposes a health endpoint for monitoring:
curl https://your-cms.com/api/health
# Response: { "status": "ok", "database": "connected" }