Celestial Background
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

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

``bash 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:
`bash 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

`bash docker compose up -d ` Docker Compose will:
  • Start PostgreSQL and wait for it to be healthy
  • Run database migrations automatically
  • Build and start the backend (waits for database health)
  • Build and start the frontend (waits for backend health)
  • Check status:
    `bash 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: `bash 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

    | Variable | Description | |----------|-------------| |
    POSTGRES_PASSWORD | Database password (16+ random bytes) | | JWT_SECRET | Access token signing key (32+ bytes) | | JWT_REFRESH_SECRET | Refresh token signing key (32+ bytes) | | MASTER_ENCRYPTION_KEY | AES-256 encryption key for PII fields |

    URLs

    | Variable | Default | Description | |----------|---------|-------------| |
    FRONTEND_URL | http://localhost:3007 | Public frontend URL | | BACKEND_URL | http://localhost:3001 | Public backend URL |

    Optional: Email (SMTP)

    | Variable | Default | Description | |----------|---------|-------------| |
    SMTP_HOST | — | SMTP server hostname | | SMTP_PORT | 587 | SMTP port | | SMTP_USER | — | SMTP username | | SMTP_PASS | — | SMTP password | | SMTP_FROM_EMAIL | noreply@omnitrex.eu | Sender address |

    Optional: Storage

    By default, file uploads are stored on the local filesystem. For production, use S3-compatible storage: | Variable | Default | Description | |----------|---------|-------------| |
    STORAGE_TYPE | local | local or s3 | | AWS_ACCESS_KEY_ID | — | S3 access key | | AWS_SECRET_ACCESS_KEY | — | S3 secret key | | AWS_REGION | — | S3 region | | AWS_S3_BUCKET | — | S3 bucket name | | AWS_S3_ENDPOINT | — | Custom endpoint (MinIO, SeaweedFS, R2) |

    Database Seeding

    Optionally seed the platform with demo data:
    `bash 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

    `bash

    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:
  • Terminate TLS at the proxy
  • Forward port 443 to frontend (3007) and API subdomain to backend (3001)
  • Set FRONTEND_URL and BACKEND_URL to your public HTTPS URLs
  • Rebuild the frontend after changing URLs (they're baked into the JS bundle at build time)
  • `bash docker compose up -d --build frontend ``

    Next Steps

    • Integrations — Connect n8n, Microsoft 365, and AI workflows