1# Deploy — systemd + logrotate 2 3Production setup for MAF on a single host. Two services + log rotation; 4both survive reboot, both restart on failure. 5 6## One-time install 7 8```bash 9sudo mkdir -p /var/log/maf 10sudo chown trbck:trbck /var/log/maf 11 12sudo cp deploy/systemd/maf-dashboard.service /etc/systemd/system/ 13sudo cp deploy/systemd/maf-worker.service /etc/systemd/system/ 14sudo cp deploy/logrotate.d/maf /etc/logrotate.d/maf 15 16sudo systemctl daemon-reload 17sudo systemctl enable --now maf-dashboard.service 18sudo systemctl enable --now maf-worker.service 19``` 20 21## Verify 22 23```bash 24systemctl status maf-dashboard maf-worker 25journalctl -u maf-dashboard -n 50 26tail -f /var/log/maf/dashboard.log 27``` 28 29The status bar at `https://maf.techvizier.com/` should turn green on 30the `kronos_refresher` and `mirofish_refresher` pills within ~60s of 31`maf-worker` coming up — that's the heartbeat key landing in Redis. 32 33## Operations 34 35| Action | Command | 36|---|---| 37| Restart dashboard (e.g. after editing templates) | `sudo systemctl restart maf-dashboard` | 38| Restart worker (e.g. after editing arena YAML) | `sudo systemctl restart maf-worker` | 39| Reload both | `sudo systemctl restart maf-dashboard maf-worker` | 40| Tail both | `sudo journalctl -u maf-dashboard -u maf-worker -f` | 41| Test logrotate without waiting | `sudo logrotate -f /etc/logrotate.d/maf` | 42| Disable autostart | `sudo systemctl disable maf-dashboard maf-worker` | 43 44## Notes 45 46* Both units use ``EnvironmentFile=-/home/trbck/workspace/MAF/.env``, so 47 secrets like ``OLLAMA_API_KEY`` and ``TT2_API_KEY`` propagate via the 48 same file ``python-dotenv`` loads at module import. Anything in ``.env`` 49 is available to both services without duplication. 50* The dashboard binds ``127.0.0.1:8420`` — fronted by your nginx / 51 cloudflare. Don't expose it directly. 52* The worker's restart loop has a budget (5 restarts / 60s window). If 53 you blow through it, the unit goes into ``failed`` and you'll see it 54 in ``systemctl status``. That usually means a config file is broken — 55 check the journal for the exception. 56* Logs hit both the systemd journal (default) AND 57 ``/var/log/maf/*.log`` (for grep-friendly tail). The logrotate rule 58 rotates the on-disk files daily, keeps 14 generations, gzips after one 59 day, and caps any single file at 100M.