# Deploying hsa-app The app runs as a **user systemd service** (no sudo). Tagged releases are pushed by CI into `~/hsa-app/releases/hsa-app-V/hsa`, and a `current` symlink (`~/hsa-app/hsa`) points at the live release. Restarting the service picks up whatever the symlink resolves to. ## Layout on the host Mutable state (DB, env, config) lives at the top of `~/hsa-app/` and survives every deploy. Only the binaries live under `releases/`. ``` ~/hsa-app/ hsa_app.sh # launcher: sources env file, exec's the binary hsa_app.env # environment (KEY=VALUE) config.json hsa.db, hsa.db-shm, hsa.db-wal # SQLite state releases/ hsa-app-V0.0.0a0/hsa hsa-app-V0.0.1/hsa hsa -> releases/hsa-app-V0.0.1/hsa # current symlink, swapped on deploy ``` ## The current symlink Create/repoint it **from inside `~/hsa-app`** so the relative target resolves against the link's own directory (running `ln -s` from `~` produces a broken link that points at `~/hsa-app/hsa-app/...`): ```bash cd ~/hsa-app chmod +x releases/hsa-app-V/hsa ln -sfn releases/hsa-app-V/hsa hsa # -f replace, -n don't follow existing link ls -l hsa # target must resolve (not broken) ``` This same `ln -sfn` + `chmod +x` is what the CI deploy step runs on each tag. ## Install the service (once) Save [hsa_app.service](hsa_app.service) to `~/.config/systemd/user/hsa_app.service`, then: ```bash loginctl enable-linger "$USER" # run the service without an active login session systemctl --user daemon-reload systemctl --user enable --now hsa_app systemctl --user status hsa_app journalctl --user -u hsa_app -f # follow logs ``` ### Why these choices - **User service** (`systemctl --user`) — no sudo, matches the home-dir deploy. `enable-linger` lets it start at boot / stay up without an interactive login. - **`Type=exec`** — `hsa_app.sh` ends in `exec "$BIN"`, so the binary becomes the unit's main process; signals and exit codes propagate correctly. - **`WorkingDirectory=%h/hsa-app`** — relative paths in the env file resolve here. The launcher's comment recommends absolute paths for `DB_PATH` / `STORAGE_DIR` / `BACKUP_DIR` / `CONFIG_PATH`; either works. - **ExecStart passes the env file as `$1`** — matches `hsa_app.sh`'s first-arg precedence, so no `/etc/hsa-app/...` file is needed. `%h` expands to the home dir. - The launcher defaults its binary to `./hsa` next to itself (`~/hsa-app/hsa`, the symlink), so a restart after a symlink swap runs the new release automatically. ## Deploy a tagged release CI pushes the binary on tag and runs the swap + restart. To do it manually: ```bash cd ~/hsa-app chmod +x releases/hsa-app-V/hsa ln -sfn releases/hsa-app-V/hsa hsa systemctl --user restart hsa_app ``` ## Roll back Every release stays under `releases/`, so rollback is a symlink repoint: ```bash cd ~/hsa-app ln -sfn releases/hsa-app-V/hsa hsa systemctl --user restart hsa_app ```