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