Skip to main content

Overview

This guide covers deploying ARCA to production environments. The monorepo structure allows you to deploy the backend and frontend independently to different platforms.

Deployment Architecture

Backend

NestJS API deployed to Node.js hosting (Railway, Heroku, VPS)

Frontend

Next.js app deployed to Vercel, Netlify, or similar

Database

PostgreSQL on managed services (Supabase, Neon, AWS RDS)

File Storage

Document storage on S3, Cloudinary, or similar

Pre-Deployment Checklist

1

Security Review

  • All secrets use strong, random values
  • JWT_SECRET is unique and secure
  • NEXTAUTH_SECRET is generated properly
  • Database credentials are strong
  • No secrets committed to git
  • Changed all default user passwords
  • Removed or disabled test accounts
  • Admin accounts use strong passwords
  • CORS_ORIGIN set to production domain(s)
  • No wildcards (*) in CORS settings
2

Build Test

Test production builds locally:
# Build both applications
npm run build

# Test backend production build
cd apps/backend
npm run start:prod

# Test frontend production build
cd apps/frontend
npm run start
Verify:
  • No build errors
  • TypeScript compilation succeeds
  • Applications start correctly
3

Database Preparation

Prepare your production database:
  • PostgreSQL database created
  • Database user has appropriate permissions
  • SSL enabled
  • Automated backups configured
  • Connection pooling set up (if needed)
4

Code Quality

Run quality checks:
# Lint check
npm run lint

# Type check
npm run check-types

Backend Deployment

Option 1: Railway

Railway offers easy deployment with automatic SSL and PostgreSQL.
1

Install Railway CLI

npm i -g @railway/cli
railway login
2

Create New Project

railway init
3

Add PostgreSQL

In Railway dashboard:
  1. Click “New” → “Database” → “PostgreSQL”
  2. Copy the DATABASE_URL connection string
4

Configure Environment Variables

railway variables set DATABASE_URL="postgresql://..."
railway variables set JWT_SECRET="your-secret"
railway variables set JWT_TOKEN_AUDIENCE="arca-api"
railway variables set JWT_TOKEN_ISSUER="arca-backend"
railway variables set JWT_TTL="3600s"
railway variables set PORT="3333"
railway variables set CORS_ORIGIN="https://your-frontend-url.com"
railway variables set NODE_ENV="production"
5

Configure Build

Create railway.json in project root:
{
  "$schema": "https://railway.app/railway.schema.json",
  "build": {
    "builder": "NIXPACKS",
    "buildCommand": "npm install && npm run build -w backend"
  },
  "deploy": {
    "startCommand": "npm run start:prod -w backend",
    "restartPolicyType": "ON_FAILURE",
    "restartPolicyMaxRetries": 10
  }
}
6

Deploy

railway up
Railway will:
  • Build your application
  • Deploy to production
  • Provide a public URL
7

Run Migrations

railway run npm run -w backend prisma migrate deploy
8

Seed Database

railway run npm run -w backend db:seed

Option 2: Heroku

1

Install Heroku CLI

# Install
npm install -g heroku

# Login
heroku login
2

Create Application

# Create app
heroku create arca-backend

# Add PostgreSQL
heroku addons:create heroku-postgresql:mini
3

Configure Environment

heroku config:set JWT_SECRET="your-secret"
heroku config:set JWT_TOKEN_AUDIENCE="arca-api"
heroku config:set JWT_TOKEN_ISSUER="arca-backend"
heroku config:set JWT_TTL="3600s"
heroku config:set CORS_ORIGIN="https://your-frontend.vercel.app"
heroku config:set NODE_ENV="production"
4

Configure Buildpack

Create Procfile in project root:
web: cd apps/backend && npm run start:prod
release: cd apps/backend && npx prisma migrate deploy
5

Deploy

git push heroku main
6

Seed Database

heroku run npm run -w backend db:seed

Option 3: Docker

Deploy using Docker containers.
1

Create Backend Dockerfile

Create apps/backend/Dockerfile:
FROM node:18-alpine AS builder

WORKDIR /app

# Copy package files
COPY package*.json ./
COPY apps/backend/package*.json ./apps/backend/

# Install dependencies
RUN npm install

# Copy application code
COPY apps/backend ./apps/backend
COPY turbo.json ./

# Generate Prisma Client
WORKDIR /app/apps/backend
RUN npx prisma generate

# Build application
WORKDIR /app
RUN npm run build -w backend

# Production stage
FROM node:18-alpine

WORKDIR /app

# Copy built application
COPY --from=builder /app/apps/backend/dist ./dist
COPY --from=builder /app/apps/backend/node_modules ./node_modules
COPY --from=builder /app/apps/backend/prisma ./prisma
COPY --from=builder /app/apps/backend/package*.json ./

EXPOSE 3333

CMD ["node", "dist/main"]
2

Create docker-compose.yml

version: '3.8'

services:
  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: arca_db
      POSTGRES_USER: arca_user
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

  backend:
    build:
      context: .
      dockerfile: apps/backend/Dockerfile
    environment:
      DATABASE_URL: postgresql://arca_user:${DB_PASSWORD}@postgres:5432/arca_db
      JWT_SECRET: ${JWT_SECRET}
      JWT_TOKEN_AUDIENCE: arca-api
      JWT_TOKEN_ISSUER: arca-backend
      JWT_TTL: 3600s
      PORT: 3333
      CORS_ORIGIN: ${FRONTEND_URL}
      NODE_ENV: production
    ports:
      - "3333:3333"
    depends_on:
      - postgres
    command: sh -c "npx prisma migrate deploy && node dist/main"

volumes:
  postgres_data:
3

Deploy

# Build and start
docker-compose up -d

# View logs
docker-compose logs -f backend

# Run seed
docker-compose exec backend npm run db:seed

Frontend Deployment

Vercel offers the best Next.js deployment experience.
1

Install Vercel CLI

npm i -g vercel
vercel login
2

Configure Project

In your repository, create vercel.json:
{
  "buildCommand": "cd ../.. && npm run build -w frontend",
  "devCommand": "cd ../.. && npm run dev -w frontend",
  "installCommand": "cd ../.. && npm install",
  "framework": "nextjs",
  "outputDirectory": "apps/frontend/.next"
}
3

Set Environment Variables

In Vercel dashboard:
  1. Go to Project Settings → Environment Variables
  2. Add:
    • NEXT_PUBLIC_API_URL: Your backend URL (e.g., https://arca-backend.railway.app)
    • NEXTAUTH_URL: Your frontend URL (e.g., https://arca.vercel.app)
    • NEXTAUTH_SECRET: Generated secret
4

Deploy

# From project root
vercel

# Or deploy to production
vercel --prod
Or connect your GitHub repository in Vercel dashboard for automatic deployments.

Option 2: Netlify

1

Install Netlify CLI

npm install -g netlify-cli
netlify login
2

Configure Build

Create netlify.toml:
[build]
  base = "apps/frontend"
  command = "cd ../.. && npm run build -w frontend"
  publish = "apps/frontend/.next"

[build.environment]
  NODE_VERSION = "18"

[[plugins]]
  package = "@netlify/plugin-nextjs"
3

Deploy

netlify deploy --prod
Set environment variables in Netlify dashboard.

Option 3: Self-Hosted

1

Build Frontend

npm run build -w frontend
2

Create Dockerfile

Create apps/frontend/Dockerfile:
FROM node:18-alpine AS builder

WORKDIR /app

COPY package*.json ./
COPY apps/frontend/package*.json ./apps/frontend/

RUN npm install

COPY apps/frontend ./apps/frontend
COPY turbo.json ./

WORKDIR /app/apps/frontend
RUN npm run build

FROM node:18-alpine

WORKDIR /app

COPY --from=builder /app/apps/frontend/.next ./.next
COPY --from=builder /app/apps/frontend/public ./public
COPY --from=builder /app/apps/frontend/node_modules ./node_modules
COPY --from=builder /app/apps/frontend/package*.json ./

ENV NODE_ENV production
ENV PORT 3000

EXPOSE 3000

CMD ["npm", "start"]
3

Deploy

docker build -t arca-frontend -f apps/frontend/Dockerfile .
docker run -p 3000:3000 \
  -e NEXT_PUBLIC_API_URL="https://api.arca.com" \
  -e NEXTAUTH_URL="https://arca.com" \
  -e NEXTAUTH_SECRET="your-secret" \
  arca-frontend

Post-Deployment

1

Verify Deployment

curl https://your-backend-url.com
Ensure the API is responding.
Open your frontend URL in a browser and verify:
  • Application loads
  • Can access login page
  • No console errors
Test a login with default credentials to verify database connectivity.
2

Change Default Passwords

Immediately change all default user passwords!
Login with each default user and update passwords:
3

Configure Monitoring

Set up monitoring and alerts:

Application Monitoring

  • Sentry for error tracking
  • LogRocket for session replay
  • New Relic for APM

Infrastructure Monitoring

  • Railway/Heroku built-in metrics
  • Uptime monitoring (UptimeRobot)
  • Database performance monitoring
4

Set Up Backups

Configure automated database backups:
  • Enable automatic backups on your database provider
  • Test restore procedure
  • Document backup/restore process

Environment-Specific Configuration

# Backend
DATABASE_URL="postgresql://user:pass@prod-db:5432/arca_prod?sslmode=require"
JWT_SECRET="<strong-random-secret>"
JWT_TTL="3600s"
CORS_ORIGIN="https://arca.yourdomain.com"
NODE_ENV="production"

# Frontend
NEXT_PUBLIC_API_URL="https://api.arca.yourdomain.com"
NEXTAUTH_URL="https://arca.yourdomain.com"
NEXTAUTH_SECRET="<strong-random-secret>"

Scaling Considerations

Backend Scaling

  • Use horizontal scaling (multiple instances)
  • Implement connection pooling (PgBouncer)
  • Add Redis for session storage
  • Use CDN for static assets

Database Scaling

  • Enable read replicas
  • Implement connection pooling
  • Add database indexes for common queries
  • Consider partitioning for large tables

Frontend Scaling

  • Vercel automatically handles scaling
  • Enable Next.js Image Optimization
  • Use ISR for static content
  • Implement client-side caching

File Storage

  • Move to S3/Cloudinary for documents
  • Use signed URLs for secure access
  • Implement CDN for file delivery

Troubleshooting

  • Verify DATABASE_URL is correct
  • Check SSL mode requirements
  • Ensure database accepts connections from deployment IP
  • Verify connection pooling settings
  • Verify CORS_ORIGIN exactly matches frontend URL (including protocol)
  • Don’t include trailing slash
  • For multiple origins, ensure proper format
  • Check browser console for exact origin being rejected
  • Check build logs for specific errors
  • Verify all dependencies are in package.json
  • Ensure TypeScript compilation succeeds locally
  • Check Node.js version matches requirements (>= 18)
  • Verify variables are set in platform dashboard
  • Restart application after setting variables
  • Check variable names (no typos)
  • For Next.js, ensure NEXT_PUBLIC_ prefix for client-side variables

Security Checklist

  • All default passwords changed
  • Strong JWT and NextAuth secrets
  • HTTPS enabled on all endpoints
  • CORS restricted to specific origins
  • Database uses SSL connections
  • Environment variables not committed to git
  • Rate limiting enabled
  • SQL injection prevention (Prisma handles this)
  • Input validation on all endpoints
  • Audit logging enabled

Next Steps

After deploying to production, make sure to:
  • Set up regular database backups
  • Monitor application logs for errors
  • Keep dependencies updated for security patches
  • Review audit logs regularly for compliance
  • Test disaster recovery procedures

Build docs developers (and LLMs) love