Documentation Index
Fetch the complete documentation index at: https://docs.markup.freddiephilpot.dev/llms.txt
Use this file to discover all available pages before exploring further.
Deployment
Markup can be deployed as a standard Next.js application using platforms such as:
- Vercel
- Docker
- VPS / Dedicated Servers
- Railway
- Coolify
- Render
The application requires:
- PostgreSQL database
- Environment variables configured
- Prisma migrations applied
Production Requirements
Before deployment, ensure you have:
- Node.js 18+
- PostgreSQL database
- WorkOS application configured
- Production environment variables configured
- HTTPS enabled for authentication callbacks
Required Environment Variables
Example production configuration:
DATABASE_URL=postgresql://user:password@host:5432/markup?sslmode=require
WORKOS_CLIENT_ID=client_xxxxx
WORKOS_API_KEY=sk_live_xxxxx
WORKOS_COOKIE_PASSWORD=secure_random_string
NEXT_PUBLIC_WORKOS_REDIRECT_URI=https://yourdomain.com/api/auth/callback
NEXT_PUBLIC_DB_PROVIDER=postgres/convex
Build the Application
Install dependencies:
Generate the Prisma client:
Build the production application:
Start the production server:
Database Migrations
Run Prisma migrations before starting production deployments:
npx prisma migrate deploy
This applies all pending migrations safely in production.
Deploying to Vercel
1. Push Repository to GitHub
Ensure your repository is committed and pushed.
2. Import Project into Vercel
- Open the Vercel dashboard
- Import the GitHub repository
- Select the project
- Configure environment variables
Add all required variables from .env.local into:
Vercel Project Settings → Environment Variables
4. Configure PostgreSQL
You can use:
- Neon
- Supabase
- Railway PostgreSQL
- Vercel Postgres
- Self-hosted PostgreSQL
Ensure SSL is enabled if required by the provider.
5. Deploy
Vercel automatically runs:
After deployment, run migrations:
npx prisma migrate deploy
Deploying with Docker
Docker Compose
services:
db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: markup
POSTGRES_PASSWORD: markup_password
POSTGRES_DB: markup
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U markup -d markup"]
interval: 10s
timeout: 5s
retries: 5
app:
build:
context: .
dockerfile: Dockerfile
args:
NEXT_PUBLIC_DB_PROVIDER: postgres
restart: unless-stopped
depends_on:
db:
condition: service_healthy
ports:
- "3001:3000"
environment:
# Database — points to the postgres service above
DATABASE_URL: postgresql://markup:markup_password@db:5432/markup
# WorkOS auth — fill these in or use a .env file
WORKOS_CLIENT_ID: ${WORKOS_CLIENT_ID}
WORKOS_API_KEY: ${WORKOS_API_KEY}
WORKOS_COOKIE_PASSWORD: ${WORKOS_COOKIE_PASSWORD}
NEXT_PUBLIC_WORKOS_REDIRECT_URI: ${NEXT_PUBLIC_WORKOS_REDIRECT_URI}
# App URL (used for CSP / redirect base)
NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:-http://localhost:3000}
# Use Postgres instead of Convex for self-hosted deployments
NEXT_PUBLIC_DB_PROVIDER: postgres
NODE_ENV: production
volumes:
postgres_data:
Dockerfile
FROM node:20-alpine AS base
# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat openssl
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --ignore-scripts --legacy-peer-deps
# Rebuild the source code only when needed
FROM base AS builder
RUN apk add --no-cache openssl
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Accept public env vars as build args so Next.js can bake them into the bundle
ARG NEXT_PUBLIC_DB_PROVIDER=postgres
ENV NEXT_PUBLIC_DB_PROVIDER=$NEXT_PUBLIC_DB_PROVIDER
# Generate Prisma client (dummy DATABASE_URL satisfies schema validation at build time)
RUN DATABASE_URL="postgresql://dummy:dummy@localhost:5432/dummy" node node_modules/prisma/build/index.js generate
# Build the Next.js app (no Convex deploy, just the Next build)
RUN npm run build:docker
# Production image
FROM base AS runner
RUN apk add --no-cache openssl
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
# Leverage Next.js standalone output
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
# Copy Prisma schema and migrations so we can run migrations at startup
COPY --from=builder /app/prisma ./prisma
COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma
COPY --from=builder /app/node_modules/@prisma ./node_modules/@prisma
COPY --from=builder /app/node_modules/prisma ./node_modules/prisma
COPY docker-entrypoint.sh ./docker-entrypoint.sh
RUN chmod +x ./docker-entrypoint.sh
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
ENTRYPOINT ["./docker-entrypoint.sh"]
Deploying on a VPS
Clone the Repository
git clone https://github.com/pphilfre/markup.git
cd markup
Install Dependencies
Create:
Add all required production variables.
Generate Prisma Client
Run Migrations
npx prisma migrate deploy
Build Application
Start Server
Reverse Proxy Example (Nginx)
server {
listen 80;
server_name 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_cache_bypass $http_upgrade;
}
}
Recommended Production Setup
Recommended stack:
- Next.js application
- PostgreSQL database
- Nginx reverse proxy
- HTTPS via Let’s Encrypt
- PM2 or Docker for process management
PM2 Example
Install PM2:
Start the application:
pm2 start npm --name markup -- run start
Save PM2 configuration:
Enable startup:
Updating Production Deployments
Pull latest changes:
Install dependencies:
Run migrations:
npx prisma migrate deploy
Rebuild application:
Restart application:
Security Recommendations
- Use HTTPS in production
- Enable PostgreSQL SSL
- Restrict database access
- Never expose
.env files publicly
- Use strong secrets
- Rotate API keys periodically
- Enable automatic backups
Troubleshooting
Prisma Migration Failures
Check migration status:
npx prisma migrate status
Application Fails to Start
Verify:
- Environment variables exist
- Database is reachable
- Prisma client is generated
- Build completed successfully
WorkOS Authentication Errors
Ensure:
- Redirect URI matches production domain
- HTTPS is enabled
- Callback URLs are configured in WorkOS
Deployment Checklist
- Environment variables configured
- PostgreSQL database running
- Prisma migrations applied
- HTTPS enabled
- WorkOS redirect URI configured
- Application successfully built
- Backups configured
- Monitoring/logging enabled