# The HEOS panel as a service. # # sudo cp /var/www/html/heos/deploy/heos-panel.service /etc/systemd/system/ # sudo systemctl daemon-reload # sudo systemctl enable --now heos-panel # # So the deploy workflow can restart it without a password prompt: # # echo 'franzz ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart heos-panel' \ # | sudo tee /etc/sudoers.d/heos-panel # sudo chmod 440 /etc/sudoers.d/heos-panel # # (that user is whoever the Gitea runner runs as -- see .gitea/workflows/deploy.yml) [Unit] Description=HEOS panel After=network-online.target Wants=network-online.target [Service] Type=simple User=franzz Group=www-data WorkingDirectory=/var/www/html/heos ExecStart=/var/www/html/heos/.venv/bin/gunicorn --worker-class gthread --workers 1 --threads 8 --bind 0.0.0.0:5443 app:app # Bind 127.0.0.1:5443 above to allow only the reverse proxy in. # # --workers stays at 1 on purpose: the Controller holds the one persistent # AVR Telnet connection and HEOS heartbeat thread, and gunicorn's workers # are separate processes -- more than one would open a second Telnet # connection, which some Denon models refuse. --threads is what gives it # concurrency instead, same as app.py's own threaded=True dev server. Restart=always RestartSec=3 [Install] WantedBy=multi-user.target