How It Works
A self-hosted TestVibe is a small set of containers orchestrated by Docker Compose. Each one replaces a piece of the cloud platform with something you run yourself.
The Services
| Service | Role | Notes |
|---|---|---|
| web | The application — the Wisej/.NET app users open in a browser. | Configured entirely from the environment; no config file. |
| postgres | The application database. | Holds accounts, projects, tests, runs, and canonical test files. |
| migrate | One-shot schema job. Applies the database schema, then exits. | Runs again on every start; it is idempotent, so already-applied changes are skipped. It also handles upgrades — a new release applies only its new schema changes. |
| blobserver | Object storage for artifacts, screenshots, videos, traces, and run bundles. | The on-prem replacement for cloud blob storage. Hands the UI and runner short-lived signed URLs. |
| runner | Executes your Playwright test runs. | The app dispatches each run here; it reaches the blob server and the site under test over the network. |
| browser | A browser host for AI feature generation and the assistant. | The app drives it in-process and assembles the generated test itself. Needs an AI key or local model. |
How They Connect
┌─────────┐
user ───▶ │ web │ ──────────────┐
└────┬────┘ │
│ ▼
┌─────────┼──────────┐ ┌──────────┐
▼ ▼ ▼ │ runner │ ──▶ your app under test
┌──────────┐ ┌──────┐ ┌────────┐ (test runs)
│ postgres │ │ blob │ │ browser│ ──▶ your app under test
└──────────┘ │server│ └────────┘ (AI generation)
└──────┘
- The web app talks to postgres (data), blobserver (artifacts), the runner (dispatching test runs), and the browser host (driving AI generation).
- The runner and browser both need network reach to the site under test and to the blob server. Make sure your application's URL is reachable from inside the stack.
- Users reach the web app at the public URL you configure — this is also where OAuth callbacks and webhooks arrive.
Startup Order
Compose enforces a strict order so the app never starts against an unprepared database:
- postgres comes up and reports healthy.
- migrate runs the schema job and exits successfully.
- blobserver comes up and reports healthy.
- web starts — only after the three above are ready.
The runner and browser are always-on services that the app calls when it needs them.
Data And Persistence
The database and object storage write to named Docker volumes, so your data survives docker compose down / up and upgrades. Tearing the stack down with volumes removed deletes it — back up the volumes before any destructive operation.