Book 1
Administrator Guide — Windows Server
Everything an operator needs to install, configure and run an OPSQAI Self-Hosted instance on a dedicated Windows Server. OPSQAI ships as a single signed OPSQAI-Setup.exe (NSIS) that stages a native Windows deployment — no Docker, no WSL, no Hyper-V. All background components run as proper Windows Services via WinSW with Event Log integration and auto-restart.
1. Prerequisites
A dedicated 64-bit Windows Server host:
- OS: Windows Server 2019, 2022 or 2025 (Standard or Datacenter), or Windows 11 Pro for evaluation. Windows Server Core is supported.
- Hardware: 4 vCPU / 8 GB RAM minimum; 8 vCPU / 16 GB RAM recommended for > 25 concurrent seats.
- Disk: 60 GB NTFS on
C:\for the application; a separate volume (e.g.D:\OPSQAI\Data) recommended forpgdata,objectsandbackups. - Privileges: a local Administrator account to run
OPSQAI-Setup.exe(services are installed underLocalSystemby default; a dedicated service account is supported). - Network: outbound HTTPS 443 to
mc.opsqai.defor license activation and signed update manifests. No inbound Internet required. - TLS: the bundled Caddy service terminates TLS on
:443(self-signed on first boot; replace with your corporate/AD-CS certificate via the Service Manager). - Not required: Docker Desktop, WSL2, Hyper-V, IIS, .NET, Node.js — everything is bundled in the installer payload.
2. Install with OPSQAI-Setup.exe
Download the signed installer from the Customer Portal, verify the Authenticode signature, then run it on the target server:
# PowerShell 7 (Administrator)
# 1. Verify Authenticode signature (issuer: OPSQAI GmbH, EV code-signing)
Get-AuthenticodeSignature .\OPSQAI-Setup.exe | Format-List Status, SignerCertificate
# 2. Interactive install
.\OPSQAI-Setup.exe
# 2b. Silent / unattended install (see docs/unattended-install.md)
.\OPSQAI-Setup.exe /S /D=C:\Program Files\OPSQAIThe installer stages the payload under C:\Program Files\OPSQAI, provisions data folders under C:\ProgramData\OPSQAI (or your chosen data volume), registers the Windows Services listed below, and opens the first-run wizard on https://localhost.
3. Windows Services (WinSW)
Each service is a WinSW-wrapped Node process registered with the Service Control Manager. Manage them with sc.exe, Get-Service, or the bundled OPSQAI Service Manager.
OpsqaiCaddy— Caddy reverse proxy, terminates TLS on:443, forwards to the platform on127.0.0.1:8080.OpsqaiPlatform— TanStack Start SSR + API (the web application).OpsqaiWorker— background jobs: RAG indexing, embeddings, scheduled backups.OpsqaiDatabase— PostgreSQL 16 Portable withpgvector,scram-sha-256auth, data inProgramData\OPSQAI\pgdata.OpsqaiUpdater— pollsmc.opsqai.defor signed update manifests (Ed25519); applies updates only on operator confirmation.
Get-Service Opsqai*
Restart-Service OpsqaiPlatform
Get-EventLog -LogName Application -Source OpsqaiPlatform -Newest 204. First-run wizard
After install, open https://localhost on the server (or your DNS name once the certificate is replaced). The wizard is single-use and self-seals when it completes. Steps:
- EULA — accept the OPSQAI Self-Hosted licence agreement.
- License — Ed25519 token issued by the Management Center; paste as-is.
- Database — use the bundled
OpsqaiDatabaseservice, or point at an external PostgreSQL 15+ withpgvector. - Object storage — local NTFS folder (default:
D:\OPSQAI\Data\objects), external S3, or Azure Blob. - AI provider — Lovable AI Gateway, Azure OpenAI, OpenAI-compatible endpoint, or local Ollama.
- SMTP — host, port, TLS mode, username, password, from-address.
- SSO (optional) — SAML or OIDC metadata URL; can be configured post-install.
- Backup destination — local path, S3, Azure Blob, or SMB/NAS.
- Doctor — end-to-end probe (DB, storage, SMTP, AI, license, TLS).
- First platform admin — email + password; bootstraps
public.user_roles.
Each step runs a Doctor probe before it accepts the value. On completion the wizard writes public.platform_config.setup_completed_at and the /first-run route becomes permanently unreachable. A lost admin uses the DR break-glass flow, not this wizard.
5. On-disk layout
C:\Program Files\OPSQAI\ # binaries (read-only after install)
├── platform\ # OpsqaiPlatform Node bundle
├── worker\ # OpsqaiWorker Node bundle
├── caddy\ # caddy.exe + Caddyfile template
├── postgres\ # PostgreSQL 16 Portable
├── winsw\ # WinSW.exe + service XMLs
└── tools\ # opsqai.cmd, opsqai-migrate.cmd
C:\ProgramData\OPSQAI\ # runtime state (writable)
├── config\opsqai.env # generated by the wizard (ACL: Administrators + service SID)
├── config\secrets.env # 0600-equivalent NTFS ACL; API keys, SMTP password
├── pgdata\ # PostgreSQL cluster (unless external DB)
├── objects\ # object storage (unless external S3/Azure)
├── backups\ # local backup target
├── logs\ # per-service rolling logs
└── tls\ # Caddy-managed or imported certificates6. Configuration (opsqai.env)
The wizard writes C:\ProgramData\OPSQAI\config\opsqai.env. Secrets are kept in a separate secrets.env file with a restricted NTFS ACL and are loaded by WinSW at service start. Edit only when services are stopped.
OPSQAI_MODE=selfhost
OPSQAI_PUBLIC_URL=https://opsqai.contoso.local
# Database (bundled PostgreSQL by default)
DATABASE_URL=postgres://opsqai@127.0.0.1:5432/opsqai
# Object storage — local NTFS
OPSQAI_OBJECT_STORE=local
OPSQAI_OBJECT_PATH=D:\OPSQAI\Data\objects
# Licensing
OPSQAI_MC_URL=https://mc.opsqai.de
# Signing keys — DO NOT LOSE; backups are encrypted with this key
OPSQAI_MASTER_KEY= # 32-byte base64, generated on first boot if empty7. Backups & restore
OpsqaiWorker runs nightly logical backups of PostgreSQL (pg_dump custom format) and copies the object store to the configured destination. Backups are encrypted with OPSQAI_MASTER_KEY. Retention and schedule are set in the Service Manager.
# Manual backup
& "C:\Program Files\OPSQAI\tools\opsqai.cmd" backup run --now
# List snapshots
& "C:\Program Files\OPSQAI\tools\opsqai.cmd" backup list
# Restore a specific snapshot (services are stopped automatically)
& "C:\Program Files\OPSQAI\tools\opsqai.cmd" restore --snapshot 2026-07-15T03-00Z --confirm8. Updates
OpsqaiUpdater polls mc.opsqai.de for signed update manifests (Ed25519). Updates are downloaded, signature-verified, and staged; the operator confirms application from the Service Manager (or unattended via opsqai.cmd update apply). Database migrations run automatically on OpsqaiPlatform boot behind a Postgres advisory lock.
# Check for updates
& "C:\Program Files\OPSQAI\tools\opsqai.cmd" update check
# Apply the staged update (stops services, migrates, restarts)
& "C:\Program Files\OPSQAI\tools\opsqai.cmd" update apply --confirm9. Migrating from the legacy Docker build
Customers who ran the pre-1.0 Docker Compose reference stack migrate onto Windows-native with the bundled migrator. It exports the Postgres database and object bucket from the Compose deployment, then imports them into the freshly installed Windows services.
# On the OLD Docker host
docker compose exec worker opsqai backup run --now --export /backup/export.opsqai
# Copy export.opsqai to the new Windows Server, then:
& "C:\Program Files\OPSQAI\tools\opsqai-migrate.cmd" `
--from C:\Transfer\export.opsqai --confirm10. Troubleshooting
- Wizard rejects license — check outbound TLS to
mc.opsqai.deand that the host clock is within 60 s of NTP (w32tm /query /status). - Service will not start —
Get-EventLog -LogName Application -Source Opsqai* -Newest 50, or inspectC:\ProgramData\OPSQAI\logs\<service>.out.log. - Caddy returns 502 —
OpsqaiPlatformis not listening on127.0.0.1:8080; usually a migration failure — check the platform log. - Embeddings stuck —
Get-Content C:\ProgramData\OPSQAI\logs\worker.out.log -Tail 200; verify AI provider quota. - Doctor page —
https://<host>/admin/doctorre-runs every probe on demand.