# Deploying Momentum Three supported shapes, one image/codebase. Pick by where it runs: | Mode | Status | Use when | Docs | |---|---|---|---| | **Docker Compose** | ✅ **canonical** (production since 2026-07-09) | Any always-on Linux host; TrueNAS SCALE | [docker/README.md](docker/README.md), `docker-compose.yml` (root), [docker/truenas-compose.yml](docker/truenas-compose.yml) | | **Local (systemd)** | ✅ maintained | Development machine, WSL, bare metal without Docker | [systemd/README.md](systemd/README.md) + unit templates in `deploy/systemd/` | | **Helm / Kubernetes** | 🚧 planned refresh | Future k8s hosting | [helm/](helm/) — the chart predates the 2026-07 architecture; starting point, not deployable | ## Docker Compose (canonical) The root `docker-compose.yml` runs the full stack self-contained: postgres 18, trading loop, dashboard (:8765), admin panel (:8767), telegram bot, transcripts pipeline, nightly scheduler, on-demand jobs, optional Grafana. The image is published to `docker.io/fez5587/momentum-app` and `ghcr.io/fez5587/momentum-app` by CI on every master push. For TrueNAS SCALE use `docker/truenas-compose.yml` (pull-only, dataset host paths, inline env). **Read the gotchas in docker/README.md before editing the YAML** — anchor expansion, per-service env, and path case-sensitivity have each caused an outage. ## Local (systemd user services) The original deployment: unit templates in `deploy/systemd/` running a git checkout + venv, config from `.env`. Still the best loop for development — tests, backtests, and research scripts run here. Keep the units **disabled** while the compose stack owns production: two loops against one Alpaca account create duplicate orders. ## Helm (future) `deploy/helm/` holds the original chart (single app deployment + CronJobs). It predates the service split, the session gate, and the env-flag inventory; the refresh is tracked in GitHub issues. Until then, compose is the way. ## Config in all modes - `.env.example` (committed, sanitized) is the full variable inventory and says which layer each belongs in. - Behavior flags that MUST be set explicitly in any deployment — silent defaults bite: `TRADING_AUTO_APPROVE=1` (else entries queue for manual approval), `ALPACA_DATA_FEED=sip`, `OLLAMA_ENABLED=true` (catalyst engine), `FMP_API_KEY` (float cache). `TRADING_SESSION_ONLY` defaults ON in deployed configs (bars after-hours entries). - Runtime overrides: the admin panel writes `data/overrides.env`, which every service loads over its baked env at boot (`runtime/env_overrides.py`).