[Unit] Description=Riksdagen API (FastAPI, serves rixdagen.se/api via nginx) Documentation=https://rixdagen.se # Postgres runs in the riksdagen-pg container, and env_manager pulls part of the # environment over the network at import time — so both must be up first. Wants=network-online.target After=network-online.target docker.service # Don't hammer a genuinely broken deploy — give up after 5 failures in 5 min so # the unit lands in `failed` where it is visible, instead of looping forever. StartLimitIntervalSec=300 StartLimitBurst=5 [Service] Type=exec User=lasse Group=lasse WorkingDirectory=/home/lasse/riksdagen # No EnvironmentFile: the app loads .env itself (config.py -> env_manager.set_env()) # and that file contains keys systemd's parser would read differently, e.g. # "LLM_MODEL =" with a trailing space. WorkingDirectory is what makes it resolve. ExecStart=/home/lasse/riksdagen/.venv/bin/uvicorn backend.app:app --host 127.0.0.1 --port 8000 # Research jobs run as detached child processes (start_new_session=True in # backend/services/research/jobs.py) precisely so a long dig survives an API # restart. The default KillMode=control-group would kill the whole cgroup on # restart and take those jobs with it, silently breaking that design. With # KillMode=process only uvicorn is signalled; any orphaned job is cleaned up by # reap_stale_jobs() and capped by MAX_JOB_RUNTIME_SECS. KillMode=process TimeoutStopSec=30 Restart=always RestartSec=5 # journalctl -u riksdagen-api -f StandardOutput=journal StandardError=journal SyslogIdentifier=riksdagen-api [Install] WantedBy=multi-user.target