What you get #
| Service | Image | Role |
|---|---|---|
db | postgres:16-alpine | Data, plus the job queue. Published on 127.0.0.1:5432 only. |
app | built from ./web | The web app, API and collaboration server on port 3000. No host port; put a reverse proxy in front. |
worker | built from ./services/worker | Emails, webhooks, push, digests, cleanup. |
scheduler | built from ./services/scheduler | Enqueues recurring jobs. |
Attachments go to a Docker volume by default, or to any S3-compatible bucket.
Deploy #
Clone and configure
Fill in at leastgit clone https://github.com/KilicerDev/trackr.git && cd trackr cp .env.example .envPOSTGRES_PASSWORD,BETTER_AUTH_SECRET(32+ random characters) and theROOT_*account. Everything else has a sensible default.Start
The app container runs migrations and seeds the root account on every start; both are idempotent.docker compose up -d --buildPut a proxy in front
Point your reverse proxy atapp:3000and forwardX-Forwarded-ProtoandX-Forwarded-Host. LeaveORIGINunset so Trackr derives its public URL from those headers.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 #
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=100MUpdating #
git pull
docker compose up -d --buildMigrations run automatically on start. The Go services never migrate; the web app owns the schema.
Scaling notes #
workerandschedulercan 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
appreplica, or ask before scaling it out.