All documentation

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 for pgdata, objects and backups.
  • Privileges: a local Administrator account to run OPSQAI-Setup.exe (services are installed under LocalSystem by default; a dedicated service account is supported).
  • Network: outbound HTTPS 443 to mc.opsqai.de for 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\OPSQAI

The 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 on 127.0.0.1:8080.
  • OpsqaiPlatform — TanStack Start SSR + API (the web application).
  • OpsqaiWorker — background jobs: RAG indexing, embeddings, scheduled backups.
  • OpsqaiDatabase — PostgreSQL 16 Portable with pgvector, scram-sha-256 auth, data in ProgramData\OPSQAI\pgdata.
  • OpsqaiUpdater — polls mc.opsqai.de for signed update manifests (Ed25519); applies updates only on operator confirmation.
Get-Service Opsqai*
Restart-Service OpsqaiPlatform
Get-EventLog -LogName Application -Source OpsqaiPlatform -Newest 20

4. 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:

  1. EULA — accept the OPSQAI Self-Hosted licence agreement.
  2. License — Ed25519 token issued by the Management Center; paste as-is.
  3. Database — use the bundled OpsqaiDatabase service, or point at an external PostgreSQL 15+ with pgvector.
  4. Object storage — local NTFS folder (default: D:\OPSQAI\Data\objects), external S3, or Azure Blob.
  5. AI provider — Lovable AI Gateway, Azure OpenAI, OpenAI-compatible endpoint, or local Ollama.
  6. SMTP — host, port, TLS mode, username, password, from-address.
  7. SSO (optional) — SAML or OIDC metadata URL; can be configured post-install.
  8. Backup destination — local path, S3, Azure Blob, or SMB/NAS.
  9. Doctor — end-to-end probe (DB, storage, SMTP, AI, license, TLS).
  10. 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 certificates

6. 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 empty

7. 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 --confirm

8. 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 --confirm

9. 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 --confirm

10. Troubleshooting

  • Wizard rejects license — check outbound TLS to mc.opsqai.de and that the host clock is within 60 s of NTP (w32tm /query /status).
  • Service will not startGet-EventLog -LogName Application -Source Opsqai* -Newest 50, or inspect C:\ProgramData\OPSQAI\logs\<service>.out.log.
  • Caddy returns 502OpsqaiPlatform is not listening on 127.0.0.1:8080; usually a migration failure — check the platform log.
  • Embeddings stuckGet-Content C:\ProgramData\OPSQAI\logs\worker.out.log -Tail 200; verify AI provider quota.
  • Doctor pagehttps://<host>/admin/doctor re-runs every probe on demand.