Files
ds-chat/deploy/systemd/ds-chat.service
T
ksmithandClaude Sonnet 5 14dc340174 Rename project from KeepItTalking to DS Chat
Renames the app's display name everywhere (page titles, PWA manifest,
TopBar, email subject lines, HMAC signature header) and its internal
technical slug from chatapp to ds-chat/ds_chat: the Python package name
and console script, the systemd unit and its user/group/paths, the deploy
scripts, the Docker container names, and the Postgres database name.

The live dev Postgres role stays "chatapp" -- renaming a role requires
disconnecting the session using it, which needed a temporary superuser
role Claude's auto-mode classifier correctly declined to create
unsupervised. Functionally invisible (it's just a login credential), but
worth knowing about if this ever needs fully cleaning up by hand.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-15 21:11:41 -06:00

55 lines
1.9 KiB
Desktop File

# /etc/systemd/system/ds-chat.service
#
# Install: sudo cp deploy/systemd/ds-chat.service /etc/systemd/system/
# sudo systemctl daemon-reload
# sudo systemctl enable --now ds-chat
#
# See ../../DEPLOYMENT.md for the full app-server setup this fits into.
# TLS termination and public-facing reverse proxying are handled by an
# external Nginx Proxy Manager instance, not anything on this box -- this
# unit just needs to be reachable on the TCP port below.
[Unit]
Description=DS Chat app server
After=network.target
[Service]
# No Type= override -- defaults to "simple", which is correct here since
# gunicorn runs in the foreground (no --daemon flag below) and doesn't send
# systemd's sd_notify readiness protocol.
User=ds-chat
Group=ds-chat
WorkingDirectory=/srv/ds-chat/backend
EnvironmentFile=/etc/ds-chat/env
Environment=PYTHONUNBUFFERED=1
# 0.0.0.0 because Nginx Proxy Manager runs on a separate host -- the actual
# security boundary is the `ufw` rule in DEPLOYMENT.md restricting this
# port to NPM's IP specifically, not the bind address. If NPM reaches this
# box over a private network interface, bind to that private IP instead
# for defense in depth (belt-and-suspenders on top of the firewall rule).
ExecStart=/srv/ds-chat/backend/.venv/bin/gunicorn app.main:app \
-k uvicorn.workers.UvicornWorker \
--workers 4 \
--bind 0.0.0.0:8000 \
--timeout 30
# alembic upgrade head deliberately does NOT run here -- with --workers 4,
# every restart would race multiple processes trying to migrate at once.
# It's an explicit step in deploy/upgrade.sh instead, run once before the
# restart that picks up the new code.
Restart=on-failure
RestartSec=2
# Baseline hardening -- not a full systemd sandboxing pass, just the
# well-understood safe defaults for a service that doesn't need to write
# anywhere outside its own working directory.
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
[Install]
WantedBy=multi-user.target