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
| Variable | Default | What it does |
|---|---|---|
PORT | 3000 | Listen port. |
VITRUS_DB | ./vitrus-cloud.db | Database file. |
VITRUS_BASE_URL | localhost | Public origin. OAuth callback URLs derive from this. |
VITRUS_APP_URL | BASE_URL/app | Where 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'"