Install & operate

Self-hosting

What you need

Bun. Nothing else — the database is embedded and there is no second service to install.

git clone <repo> /opt/vitrus && cd /opt/vitrus
bun install
bun run build:tracker
bun run cloud

Environment variables

VariableDefaultWhat it does
PORT3000Listen port.
VITRUS_DB./vitrus-cloud.dbDatabase file.
VITRUS_BASE_URLlocalhostPublic origin. OAuth callback URLs derive from this.
VITRUS_APP_URLBASE_URL/appWhere the landing page's login links point.
VITRUS_SECURE—1 marks cookies Secure (required behind HTTPS).
VITRUS_EMAIL_KEY—Resend API key (or any Resend-compatible endpoint via VITRUS_EMAIL_ENDPOINT): digests, invitations, password resets. Unset = nothing is sent, and the dashboard says so.
VITRUS_EMAIL_FROM—Sender address.
VITRUS_TRACK_SITE—Let the landing page measure itself (dogfood).
GOOGLE_CLIENT_ID / _SECRET—Sign in with Google.
GITHUB_CLIENT_ID / _SECRET—Sign in with GitHub.
OLLAMA_URL—Local LLM for digest phrasing.

If a provider key is absent, that sign-in button is not rendered at all — you never meet a button that does nothing.

Reverse proxy and country data

The country breakdown is read only from your proxy's header. We do not bundle a GeoIP database — a 60+ MB file with a monthly update cycle would break the one-command install on its own. Supported headers: Cloudflare (CF-IPCountry), Vercel, Fly, CloudFront, Netlify. With none of them the country table stays empty and the dashboard says why.

City, region and coordinates (the Globe's Timeline, Coordinates and Subdivisions modes) need one more step on Cloudflare: Rules → Settings → Managed Transforms → Add visitor location headers. That adds cf-ipcity, cf-region-code, cf-iplatitude and cf-iplongitude. Vercel and CloudFront send their equivalents without extra setup. Coordinates are rounded to 0.1° (about 11 km) before they are stored — city precision, which is all IP geolocation honestly has — and the IP itself is never stored. Without these headers the Globe works at country level and says what is missing.

Backups

WAL mode means three files; do not copy them while the process is running:

sqlite3 /var/lib/vitrus/vitrus.db ".backup '/backup/vitrus.db'"