Back to Academy

Getting Started — Self-Hosting Omnitrex GRC

Deploy the Omnitrex GRC platform with Docker Compose in under 10 minutes. Covers PostgreSQL setup, environment configuration, and first login.

4 min read·Omnitrex Team

Prerequisites

  • Docker and Docker Compose installed
  • Node.js 22+ (for generating secrets)
  • Ports 3001, 3007, and 5432 available

Architecture

Omnitrex GRC runs as three containers:

  • PostgreSQL 16 — Database on port 5432
  • Backend — Express 5 + Prisma 6 API on port 3001
  • Frontend — Next.js 15 + React 19 on port 3007
A fourth ephemeral container runs database migrations on startup.

Step 1: Clone and Configure

git clone https://github.com/omnitrex-grc/omnitrex-platform.git
cd omnitrex-platform
cp .env.example .env

Step 2: Generate Secrets

Every deployment needs unique cryptographic secrets. Generate them with Node.js:

node -e "console.log('JWT_SECRET=' + require('crypto').randomBytes(32).toString('hex'))"
node -e "console.log('JWT_REFRESH_SECRET=' + require('crypto').randomBytes(32).toString('hex'))"
node -e "console.log('MASTER_ENCRYPTION_KEY=' + require('crypto').randomBytes(32).toString('hex'))"
node -e "console.log('POSTGRES_PASSWORD=' + require('crypto').randomBytes(16).toString('hex'))"

Paste the output into your .env file, replacing the placeholder values.

Important: MASTER_ENCRYPTION_KEY encrypts PII fields (AES-256). Store it safely — it cannot be rotated without data loss.

Step 3: Configure URLs

For local development, the defaults work out of the box:

FRONTEND_URL=http://localhost:3007
BACKEND_URL=http://localhost:3001

For production, set these to your actual domain:

FRONTEND_URL=https://app.yourdomain.com
BACKEND_URL=https://api.yourdomain.com

Step 4: Start the Platform

docker compose up -d

Docker Compose will:

  1. Start PostgreSQL and wait for it to be healthy
  2. Run database migrations automatically
  3. Build and start the backend (waits for database health)
  4. Build and start the frontend (waits for backend health)
Check status:
docker compose ps

All services should show healthy status within 2-3 minutes.

Step 5: First Login

Open http://localhost:3007 in your browser. The platform uses email + password authentication.

To create the first admin user, use the registration endpoint:

curl -X POST http://localhost:3001/api/auth/self-service-signup \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@yourcompany.com",
    "password": "YourSecurePassword123!",
    "firstName": "Admin",
    "lastName": "User",
    "companyName": "Your Company"
  }'

This creates both your organisation (Group) and your admin user. Log in at http://localhost:3007 with those credentials.

Environment Variable Reference

Required

VariableDescription
POSTGRES_PASSWORDDatabase password (16+ random bytes)
JWT_SECRETAccess token signing key (32+ bytes)
JWT_REFRESH_SECRETRefresh token signing key (32+ bytes)
MASTER_ENCRYPTION_KEYAES-256 encryption key for PII fields

URLs

VariableDefaultDescription
FRONTEND_URLhttp://localhost:3007Public frontend URL
BACKEND_URLhttp://localhost:3001Public backend URL

Optional: Email (SMTP)

VariableDefaultDescription
SMTP_HOSTSMTP server hostname
SMTP_PORT587SMTP port
SMTP_USERSMTP username
SMTP_PASSSMTP password
SMTP_FROM_EMAILnoreply@omnitrex.euSender address

Optional: Storage

By default, file uploads are stored on the local filesystem. For production, use S3-compatible storage:

VariableDefaultDescription
STORAGE_TYPElocallocal or s3
AWS_ACCESS_KEY_IDS3 access key
AWS_SECRET_ACCESS_KEYS3 secret key
AWS_REGIONS3 region
AWS_S3_BUCKETS3 bucket name
AWS_S3_ENDPOINTCustom endpoint (MinIO, SeaweedFS, R2)

Database Seeding

Optionally seed the platform with demo data:

docker compose exec backend npx prisma db seed

Available seed scripts:

  • seed-domains — Domain definitions only (minimal, recommended)
  • seed-demo — Full demo company with example data
  • seed-users — Pre-configured user accounts

Backups

# Export
docker compose exec postgres pg_dump -U omnitrex omnitrex > backup.sql

Restore

docker compose exec -i postgres psql -U omnitrex omnitrex < backup.sql

Production Deployment

For production, place a reverse proxy (Caddy, Nginx, or Traefik) in front of the containers:

  1. Terminate TLS at the proxy
  2. Forward port 443 to frontend (3007) and API subdomain to backend (3001)
  3. Set FRONTEND_URL and BACKEND_URL to your public HTTPS URLs
  4. Rebuild the frontend after changing URLs (they're baked into the JS bundle at build time)
docker compose up -d --build frontend

Next Steps