TrackerHelp

Self-host Tracker

Tracker's core is AGPLv3 and runs anywhere you can run a Node.js app and a Postgres database. This page covers the three deployment shapes most teams use; pick the one that fits your stage.

1. Local — for evaluation and development

The fastest way to see Tracker working end-to-end on your own machine. Postgres in Docker, Tracker via npm run dev. About 5 minutes from clone to first sign-in.

Prerequisites

  • Node.js 22.x.
  • Docker Desktop or any Docker-compatible runtime.
  • Git.

Steps

# 1. Clone
git clone https://gitlab.com/jalderman/tracker.git
cd tracker

# 2. Install dependencies
npm install

# 3. Start a Postgres container for local dev. Pick any password
#    you like for the local DB.
docker run -d --name tracker-dev-db \
  -e POSTGRES_USER=tracker \
  -e POSTGRES_PASSWORD=CHANGEME \
  -e POSTGRES_DB=tracker \
  -p 5432:5432 \
  postgres:16.13-alpine

# 4. Copy .env.example to .env and fill it in. The minimum:
#    - DATABASE_URL with the password from step 3
#    - AUTH_SECRET (generate one with the command in the file)
#    - MAIL_DRIVER=none (skips email entirely; signups auto-verify)
cp .env.example .env
${EDITOR:-vi} .env

# 5. Apply the schema
npx prisma migrate deploy

# 6. Bootstrap a first admin user via CLI
npm run admin:create
# Prompts you for email + name; prints a generated password.
# Save it — you'll need it for first sign-in.

# 7. Start Tracker
npm run dev

Open http://localhost:3000, sign in with the email + generated password from step 6. You're in.

Note on email: MAIL_DRIVER=none auto-verifies new signups and skips outbound email entirely — fine for evaluation. To wire SMTP for password reset and verification, see docs/ops/email-and-admin-bootstrap.md in the repo.

2. Production — Kubernetes via the bundled Ansible playbook

The path the Tracker maintainers use to deploy production instances. Ships an opinionated Ansible playbook that produces a repeatable Kubernetes deployment with sensible defaults.

Prerequisites

  • A Kubernetes cluster (1.30+; tested against 1.35). A ReadWriteOnce StorageClass with allowVolumeExpansion: true for Postgres.
  • An image registry the cluster can pull from (Harbor, GHCR, ECR, Docker Hub).
  • An ingress controller (ingress-nginx is the default).
  • Ansible 2.16+ on your workstation.
  • Optional: cert-manager (for public TLS), an SMTP relay (for password-reset / email verification), external DNS (for a real hostname).

Steps

  1. Read docs/ops/infrastructure-requirements.md for the full sizing and dependency table.
  2. Build a Tracker image in your registry (Dockerfile is at the repo root).
  3. Edit ansible/group_vars/ for your cluster — image registry, hostnames, Postgres backup mode (local | s3 | none), email settings.
  4. Apply: ansible-playbook deploy.yml.
  5. Bootstrap the first admin user inside the cluster: kubectl exec -n tracker deploy/tracker-app -- npm run admin:create.

Sizing: a 50-user instance fits comfortably in 1 vCPU / 1Gi memory per pod, with Postgres starting at 5Gi storage and growing on demand. Full per-component breakdown in the infrastructure-requirements doc.

3. Single-host (docker-compose, Render, Fly, etc.)

A docker-compose recipe for one-host self-host hasn't shipped yet — there's an open issue against ROADMAP.md tracking it. Until then, the local-dev steps above also work for a small production deployment if you swap npm run dev for npm run build && npm run start and run the Postgres container with persistent storage and a real password.

Platform-as-a-service deploys (Render, Fly, Railway, etc.) generally work — Tracker is a stock Next.js app — but aren't officially supported. The provider's standard Next.js + Postgres recipe applies.

After deploy

  • Test the backup/restore drill before you put real data in. Runbook: docs/ops/postgres-backup-restore.md.
  • If you plan to use commercial / overlay features later, see docs/ops/licensing.md for how the license-token verification works (offline, Ed25519-signed; no phone-home).
  • Wire the MCP from your team's laptops: Claude Code + MCP.

Upgrades

Self-host tracks tagged releases (the SaaS instance runs main). To upgrade:

git fetch --tags
git checkout v<release>
npm install
npx prisma migrate deploy
# k8s: rebuild image + ansible-playbook deploy.yml --tags app
# local: npm run build && npm run start

Migrations are designed to be safe to apply unattended; destructive schema changes go through a two-release deprecation (add → dual-write → remove). You can always upgrade one tag at a time.

Help

Everything operational lives under docs/ops/ in the repo. If something is missing or wrong, open an issue on the GitLab project and tag it docs.