Skip to content
Trackr beta
esc
Type to search. Use ↑ ↓ to move, ↵ to open.
Self-hosting

Docker Compose

Run your own Trackr with Postgres, an SMTP server and optional object storage. One compose file, four containers, no message broker.

Updated 1 Sept 2026 beta 1 min read

What you get #

ServiceImageRole
dbpostgres:16-alpineData, plus the job queue. Published on 127.0.0.1:5432 only.
appbuilt from ./webThe web app, API and collaboration server on port 3000. No host port; put a reverse proxy in front.
workerbuilt from ./services/workerEmails, webhooks, push, digests, cleanup.
schedulerbuilt from ./services/schedulerEnqueues recurring jobs.

Attachments go to a Docker volume by default, or to any S3-compatible bucket.

Deploy #

  1. Clone and configure

    git clone https://github.com/KilicerDev/trackr.git && cd trackr
    cp .env.example .env
    Fill in at least POSTGRES_PASSWORD, BETTER_AUTH_SECRET (32+ random characters) and the ROOT_* account. Everything else has a sensible default.
  2. Start

    docker compose up -d --build
    The app container runs migrations and seeds the root account on every start; both are idempotent.
  3. Put a proxy in front

    Point your reverse proxy at app:3000 and forward X-Forwarded-Proto and X-Forwarded-Host. Leave ORIGIN unset so Trackr derives its public URL from those headers.
  4. Sign in

    Open your domain, sign in with the root account, create your internal organization and invite the team.

Email #

Set SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS and EMAIL_FROM. If SMTP_HOST is empty, the worker logs emails instead of sending them, which is useful for a first run.

Storage #

.env ini
STORAGE_DRIVER=local          # or s3
STORAGE_LOCAL_DIR=/app/data/attachments
# S3-compatible
S3_ENDPOINT=https://s3.eu-central-1.amazonaws.com
S3_REGION=eu-central-1
S3_BUCKET=trackr-attachments
S3_ACCESS_KEY_ID=
S3_SECRET_ACCESS_KEY=
S3_FORCE_PATH_STYLE=false
BODY_SIZE_LIMIT=100M

Updating #

bash
git pull
docker compose up -d --build

Migrations run automatically on start. The Go services never migrate; the web app owns the schema.

Scaling notes #

  • worker and scheduler can run with any number of replicas; the queue uses row locks, so nothing is processed twice.
  • The web app's live-update stream and permission cache are single-process. Run one app replica, or ask before scaling it out.
Edit this page on GitHub