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
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:
- 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)
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
| 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:
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:
- Terminate TLS at the proxy
- Forward port 443 to frontend (3007) and API subdomain to backend (3001)
- Set
FRONTEND_URLandBACKEND_URLto your public HTTPS URLs - Rebuild the frontend after changing URLs (they're baked into the JS bundle at build time)
docker compose up -d --build frontend
Next Steps
- Platform Guide — Learn how domains, nodes, and links work
- Developer Guide — Set up the CLI and MCP servers
- Integrations — Connect n8n, Microsoft 365, and AI workflows