Skip to content

Installation & Deployment

Set up AuthVital for local development or production deployment.

Prerequisites

  • Node.js 18 or later
  • PostgreSQL 13 or later
  • Docker (optional, for containerized deployment)

Local Development

The fastest way to get AuthVital running locally:

# Clone the repository
git clone https://github.com/your-org/authvital.git
cd authvital

# Copy environment files
cp .env.example .env
cp backend/.env.example backend/.env

# Start all services
docker-compose up -d

This starts three services in order:

  1. PostgreSQL on port 5432
  2. Migrations — runs schema migrations and bootstrap, then exits
  3. AuthVital API on port 8080 (serves API + frontend)

Access the admin panel at: http://localhost:8080/admin

Option 2: Manual Setup

1. Set Up PostgreSQL

# macOS with Homebrew
brew install postgresql@15
brew services start postgresql@15

# Create database
createdb authvital

Or use Docker for just the database:

⚠️ Quick Start Values - Replace for Production

The examples below use localdev123 as a placeholder password for quick local testing.

Before deploying to production:

  • Generate a secure database password: openssl rand -base64 32
  • Generate a secure signing key: openssl rand -hex 32
  • Store secrets in a secret manager (not in code or .env files)
docker run -d \
  --name authvital-db \
  -e POSTGRES_USER=authvital \
  -e POSTGRES_PASSWORD=localdev123 \
  -e POSTGRES_DB=authvital \
  -p 5432:5432 \
  postgres:15

2. Configure Environment

cd backend
cp .env.example .env

Edit .env:

# Database
DATABASE_URL=postgresql://authvital:localdev123@localhost:5432/authvital

# Application
BASE_URL=http://localhost:8000
PORT=8000
NODE_ENV=development

# Security (generate a new one!)
MASTER_SECRET=your-32-byte-hex-string-here

# Cookie (false for local HTTP)
COOKIE_SECURE=false

# Super Admin (created on first run)
SUPER_ADMIN_EMAIL=admin@localhost

Generate a secure signing key:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

3. Install Dependencies

# Backend
cd backend
npm install

# Frontend (optional, for local UI development)
cd ../frontend
npm install

4. Run Migrations

cd backend
npx prisma migrate dev

4b. Seed Test Data (Optional)

AuthVital includes a YAML-based seed configuration for quickly bootstrapping a local environment with test users, tenants, applications, and roles.

# Navigate to the backend package
cd packages/backend

# Copy the example seed config and customize it
cp prisma/seed.config.example.yaml prisma/seed.config.yaml

# Run the seed
npm run prisma:seed

The seed config file (prisma/seed.config.yaml) lets you define:

Section What it configures
instance Instance name, sign-up rules, branding
super_admin Admin panel login credentials
applications OAuth clients with redirect URIs (default: http://localhost:5173)
applications[].roles Application-level roles (e.g., Admin, Editor, Viewer)
tenants Organizations / tenants
users Test users with passwords, tenant memberships, and role assignments

See prisma/seed.config.example.yaml for a fully-commented template with examples.

Re-running the seed

The seed is idempotent — all operations use upsert, so you can re-run it safely. To reset the database and re-seed from scratch:

npm run seed:fresh

5. Start Development Server

# Backend only
npm run start:dev

# Or run backend + frontend together
# Terminal 1:
cd backend && npm run start:dev

# Terminal 2:
cd frontend && npm run dev

Production Deployment

Cloud Run (Google Cloud)

AuthVital is designed for Cloud Run with a two-mode deployment pattern:

┌─────────────────────────────────────────────────────────────────┐
│ CI/CD Pipeline                                                   │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  1. Build Docker Image                                          │
│     └─> Push to Artifact Registry                               │
│                                                                  │
│  2. Deploy Migration Job                                        │
│     └─> Cloud Run Job (runs migrations)                         │
│                                                                  │
│  3. Execute Migration Job                                       │
│     └─> Wait for completion                                     │
│                                                                  │
│  4. Deploy API Service                                          │
│     └─> Cloud Run Service (fast startup!)                       │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

1. Build and Push Image

# Build the image
docker build -t gcr.io/PROJECT_ID/authvital:latest ./backend

# Push to Artifact Registry
docker push gcr.io/PROJECT_ID/authvital:latest

2. Create Cloud SQL Database

gcloud sql instances create authvital-db \
  --database-version=POSTGRES_15 \
  --tier=db-f1-micro \
  --region=us-central1

gcloud sql databases create authvital \
  --instance=authvital-db

3. Set Up Secrets

# Database password
echo -n "your-db-password" | gcloud secrets create DB_PASSWORD --data-file=-

# Master secret (encrypts JWT signing keys at rest)
echo -n "$(openssl rand -hex 32)" | gcloud secrets create MASTER_SECRET --data-file=-

# SendGrid API key (for emails)
echo -n "SG.xxx" | gcloud secrets create SENDGRID_API_KEY --data-file=-

4. Deploy Migration Job

gcloud run jobs create authvital-migration \
  --image=gcr.io/PROJECT_ID/authvital:latest \
  --command="./migrate.sh" \
  --set-cloudsql-instances=PROJECT_ID:REGION:authvital-db \
  --set-secrets=DB_PASSWORD=DB_PASSWORD:latest,MASTER_SECRET=MASTER_SECRET:latest \
  --set-env-vars="DB_HOST=/cloudsql/PROJECT_ID:REGION:authvital-db,DB_USERNAME=postgres,DB_DATABASE=authvital,BASE_URL=https://auth.yourdomain.com"

5. Run Migrations

gcloud run jobs execute authvital-migration --wait

6. Deploy API Service

gcloud run deploy authvital \
  --image=gcr.io/PROJECT_ID/authvital:latest \
  --set-cloudsql-instances=PROJECT_ID:REGION:authvital-db \
  --set-secrets=DB_PASSWORD=DB_PASSWORD:latest,MASTER_SECRET=MASTER_SECRET:latest \
  --set-env-vars="DB_HOST=/cloudsql/PROJECT_ID:REGION:authvital-db,DB_USERNAME=postgres,DB_DATABASE=authvital,BASE_URL=https://auth.yourdomain.com,NODE_ENV=production" \
  --allow-unauthenticated \
  --port=8000

Kubernetes / Helm

# values.yaml
image:
  repository: gcr.io/PROJECT_ID/authvital
  tag: latest

env:
  BASE_URL: https://auth.yourdomain.com
  NODE_ENV: production
  COOKIE_SECURE: "true"

secrets:
  - name: DATABASE_URL
    secretRef: authvital-secrets
    key: database-url
  - name: MASTER_SECRET
    secretRef: authvital-secrets
    key: signing-key

postgresql:
  enabled: true  # Or use external database

Docker (Self-hosted)

# docker-compose.prod.yml
version: '3.8'

services:
  db:
    image: postgres:15
    environment:
      POSTGRES_USER: authvital
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: authvital
    volumes:
      - postgres_data:/var/lib/postgresql/data

  app:
    image: gcr.io/PROJECT_ID/authvital:latest
    ports:
      - "8000:8000"
    environment:
      DATABASE_URL: postgresql://authvital:${DB_PASSWORD}@db:5432/authvital
      BASE_URL: https://auth.yourdomain.com
      NODE_ENV: production
      COOKIE_SECURE: "true"
      MASTER_SECRET: ${MASTER_SECRET}
    depends_on:
      - db

volumes:
  postgres_data:

Environment Variables

Required

Variable Description Example
DATABASE_URL PostgreSQL connection string postgresql://user:pass@host:5432/db
BASE_URL Public URL of AuthVital https://auth.yourdomain.com
MASTER_SECRET 32-byte hex master key (encrypts signing keys at rest) 0123456789abcdef... (64 chars)

Optional

Variable Description Default
PORT Server port 8000
NODE_ENV Environment development
COOKIE_SECURE Secure cookie flag true in production
CORS_ORIGINS Additional CORS origins (none)
SENDGRID_API_KEY SendGrid API key (logs emails to console)
SENDGRID_FROM_EMAIL From address for emails noreply@yourdomain.com
SUPER_ADMIN_EMAIL Initial super admin email (no auto-create)
KEY_ROTATION_INTERVAL_SECONDS JWT key rotation interval 604800 (7 days)

Cloud SQL (GCP)

When using Cloud SQL, configure these instead of DATABASE_URL:

Variable Description
DB_HOST Cloud SQL socket path
DB_USERNAME Database username
DB_PASSWORD Database password (from Secret Manager)
DB_DATABASE Database name

First Login

After deployment:

  1. Navigate to https://auth.yourdomain.com/admin
  2. If SUPER_ADMIN_EMAIL was set, check email for password reset link
  3. Or use the default credentials (development only)
  4. Immediately change the password and enable MFA

Health Checks

AuthVital exposes a health endpoint:

curl https://auth.yourdomain.com/health
# {"status":"ok","timestamp":"2024-01-15T..."}

For Kubernetes/Cloud Run:

# Liveness probe
livenessProbe:
  httpGet:
    path: /health
    port: 8000
  initialDelaySeconds: 10
  periodSeconds: 30

# Readiness probe
readinessProbe:
  httpGet:
    path: /health
    port: 8000
  initialDelaySeconds: 5
  periodSeconds: 10

Troubleshooting

Database Connection Failed

Error: Can't reach database server at `localhost`:`5432`
  1. Ensure PostgreSQL is running
  2. Check DATABASE_URL is correct
  3. Verify network connectivity (especially in containers)

Migration Failed

Error: P3009 migrate found failed migrations
# Reset failed migration (development only!)
npx prisma migrate reset

# Or resolve manually
npx prisma migrate resolve --rolled-back MIGRATION_NAME

Token Validation Failed

  1. Ensure BASE_URL matches the issuer in JWTs
  2. Verify MASTER_SECRET is the same across all instances (it decrypts the shared signing keys)
  3. Check token hasn't expired

CORS Errors

Add your frontend origin to CORS_ORIGINS:

CORS_ORIGINS=https://app.yourdomain.com,https://admin.yourdomain.com