Interactive installer and management CLI for Linux, macOS and Windows. Clones the main branches of TrackGeek/web and TrackGeek/api, builds production images, starts PostgreSQL and Redis, deploys Prisma migrations and seeds the database. Installs tg start, tg stop, tg update, tg help and tg autostartup on/off.
Run in an interactive terminal. The installer sets up missing Docker automatically, starts it and waits until it is ready before continuing. Linux uses the official Docker installer and starts the service; macOS and Windows download and install Docker Desktop directly, without requiring Homebrew or winget for Docker. Administrator password prompts and Docker Desktop setup dialogs may appear. Windows may require WSL setup, virtualization support and a restart; if requested, restart and run the same command again. Docker Desktop installation accepts its subscription agreement using the official installer flag. See the official Linux, macOS and Windows instructions for supported systems.
Internet access and enough disk space/RAM to build both applications are required. Bun is installed by the bootstrap when missing; Git is installed using supported system package managers. Linux needs curl and unzip. Docker Compose 2.30+ and Linux containers are required and checked automatically. Native Windows uses PowerShell, not install.sh.
Linux / macOS:
curl -fsSL https://raw.githubusercontent.com/TrackGeek/selfhost/main/install.sh -o /tmp/trackgeek-install.sh && bash /tmp/trackgeek-install.shWindows PowerShell:
$script = Join-Path $env:TEMP "trackgeek-install.ps1"; Invoke-WebRequest https://raw.githubusercontent.com/TrackGeek/selfhost/main/install.ps1 -OutFile $script; & $scriptFrom a local checkout:
bash install.sh.\install.ps1selfhost/
├── src/
│ ├── installer.ts
│ ├── cli.ts
│ ├── config/
│ │ └── env.ts
│ ├── docker/
│ │ ├── setup.ts
│ │ └── runtime.ts
│ ├── management/
│ │ ├── autostartup.ts
│ │ ├── commands.ts
│ │ └── install.ts
│ └── system/
│ ├── filesystem.ts
│ ├── git.ts
│ └── process.ts
├── tests/
├── templates/
├── install.sh
└── install.ps1
installer.ts coordinates the installation wizard; cli.ts dispatches management commands. Configuration parsing and validation live in config/. Docker installation/startup lives in docker/. Service lifecycle and CLI registration live in management/. Shared filesystem, process and Git PATH helpers live in system/. Tests and deployment templates have their own directories. The root bootstrap scripts support both local checkouts and remote downloads of this layout.
Use bun run start for the wizard, bun test for validation and bun run types for TypeScript checks.
The wizard asks for installation directory, ports, public browser URLs, network binding and API credentials. It writes <install-dir>/.env, api/.env, web/.env and .trackgeek.json. Passwords and the Better Auth secret are generated cryptographically. Existing secrets and volumes are retained when rerunning. Clones are reused without automatically updating or resetting code. Keep the installation directory private; Unix configuration files use mode 0600. Windows inherits filesystem permissions, so restrict its ACL to your account.
The wizard requires IMGBB_API_KEY, HARDCOVER_API_KEY, TMDB_API_KEY, IGDB_CLIENT_ID and IGDB_CLIENT_SECRET for image uploads and media lookup. Empty or whitespace-only credentials are rejected. RESEND_API_KEY and RESEND_FROM remain required; configure the sender using a verified Resend domain.
OAuth client IDs/secrets and DISCORD_BOT_TOKEN are optional and can be configured individually in the wizard. Empty optional integrations leave their corresponding features unavailable. No OAuth applications or external service accounts are created automatically.
Stripe is optional and disabled by default for new installations: declining it clears STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET. Without a secret key, the API starts normally, prices/perks are empty, and checkout/webhook requests return 503 STRIPE_NOT_CONFIGURED. Enabling webhooks also requires a webhook secret. Dataxamas is optional: declining it leaves VITE_DATAXAMAS_API_KEY empty and disables browser/server tracking.
New installations use web port 2026 (http://localhost:2026) and API port 408 (http://localhost:408). The wizard displays these settings; press Enter to accept them or choose No to customize ports, public URLs and network access. Existing installations keep their saved settings. Changing a local port also updates its suggested localhost URL. API and web must have distinct ports. PostgreSQL and Redis are accessible only inside the Compose network. The default binds web/API to 127.0.0.1. For access from another device, set URLs to a hostname/IP that its browser can reach and select network access. For public hosting, configure a reverse proxy, DNS, TLS and firewall yourself. The installer does not provision domains or HTTPS. Passkeys require HTTPS except on localhost.
The production seed inserts the API's reference data (medals and missions); it does not create demo users with shared passwords or a media catalogue. Create your account through the web interface. The seed runs after migrations and before the API starts; healthchecks gate service startup.
The installer saves a standalone Bun CLI in <install-dir>/.trackgeek/ and registers a tg command for your user. It works from any directory and manages the installation selected in the wizard. Linux/macOS launchers live in ${BUN_INSTALL:-~/.bun}/bin; Windows uses %LOCALAPPDATA%\TrackGeek\bin and adds it to your user PATH. Open a new terminal after installing. If the command is unavailable on Linux/macOS, add the launcher directory to PATH using the command shown by the installer. When installing multiple directories, the latest installation becomes the target of the user command. Existing installations gain the command by rerunning the installer.
tg start
tg stop
tg update
tg help
tg autostartup on
tg autostartup offhelp explains every command and works without a completed installation; --help, -h and invoking tg without arguments show the same help. Invalid commands or extra arguments return a nonzero exit code.
start starts Docker automatically when needed, then starts the Compose services and waits for healthy API/web containers. stop stops only API and web; Docker, PostgreSQL, Redis and their volumes stay running. If Docker is already stopped, stop does not start or install it. Linux requests administrator access when required.
update fetches both GitHub main branches and advances the API/web clones using fast-forward merges. Both repositories must be on main, have the expected TrackGeek origin and have no local changes, untracked files or local commits. Ignored configuration files such as .env are retained. Both repositories are checked before either checkout is changed. The command builds production images while existing services remain running, then stops API/web, removes the completed initialization container and starts services again. This reruns migrations and the production seed before the API starts. Updates run on command, without a background scheduler; they update API/web source, using the installed Compose/Dockerfile templates. Rerun the installer to refresh the CLI and templates.
If fetching or repository validation fails, checkouts and running services are unchanged. A build failure leaves existing services running with the previous images, while source checkouts may already contain the new commits; fix the build and rerun tg update. Migration/startup failures return a nonzero exit code and require checking Compose logs; volumes and configuration remain intact. Database migrations are not automatically rolled back. Newly required configuration variables must be configured by rerunning the wizard before retrying an update.
autostartup on registers automatic startup for Docker, PostgreSQL, Redis, initialization, API and web using the installed CLI. It takes effect at the next boot/login; use tg start to start the infrastructure immediately. Startup uses existing images and configuration, waits for healthy services and never runs update. Repeating on replaces the same startup registration rather than adding duplicates. Registration uses absolute Bun/CLI paths, so it does not depend on your interactive shell's PATH. Keep Bun and the installation directory in place.
- Linux: requires systemd and a system Docker Engine service named
docker.service. Administrator access may be requested to install/etc/systemd/system/trackgeek.serviceand enable it alongside Docker. Startup runs at boot without an interactive login, under the account that rantg autostartup on; non-root services receive thedockersupplementary group for socket access. The service retries failed startup every 30 seconds. Check startup logs withjournalctl -u trackgeek.service. Homes or installation directories that require an interactive login to unlock must be available at boot. Linux systems without systemd and Docker Desktop/rootless-only installations are not supported by this boot integration. - macOS: writes
~/Library/LaunchAgents/com.trackgeek.startup.plist. Startup runs when that user logs in, starts Docker Desktop when needed and retries failures every 30 seconds. Logs are saved to<install-dir>/.trackgeek/startup.log. - Windows: registers a Task Scheduler task named
TrackGeekStartup-<user SID>, triggered when that user logs in. It runs under that account without storing its password, starts Docker Desktop when needed and retries failures up to three times, one minute apart. Inspect Task Scheduler for execution results.
macOS and Windows require a user login for Docker Desktop; this integration does not run it before login. Complete Docker Desktop's first-run setup before relying on automatic startup. The latest autostartup on registration targets the current installation (system-wide on Linux; per user on macOS/Windows).
autostartup off removes TrackGeek's startup registration without stopping the infrastructure or disabling Docker, other tasks, or other services. Both on and off may start Docker to update existing TrackGeek containers to the on-failure restart policy. The Compose template uses the same policy: crashed containers restart, but restarting Docker alone does not bring them back. This keeps off effective after reboot, including when Docker has its own startup registration. Automatic TrackGeek startup is disabled by default for new installations. To stop the whole stack immediately, use docker compose stop in the installation directory.
For logs, status and manual Compose management, run inside the installation directory. Use sudo docker instead of docker if the installer used administrator access on Linux.
docker compose ps
docker compose logs -f
docker compose stop
docker compose up -d --waitRerun the installer to change configuration and rebuild. Web environment values are baked into its build; changing web/.env alone does not change the running frontend. The root .env supplies web build arguments, while api/.env is injected at runtime using Compose's raw format. API-only manual changes need docker compose up -d --force-recreate api.
Before running tg update or new migrations, back up the database and configuration. Review upstream changes before updating. No automatic destructive database reset or rollback is performed. docker compose down retains data volumes; adding --volumes permanently deletes them.
docker compose exec -T postgres pg_dump -U trackgeek -d trackgeek > trackgeek.sqlKeep database dumps private. On Windows PowerShell, use a binary-safe output method or run the backup command in a shell that preserves UTF-8 output.
