[Unit] Description=socialmag dashboard file server (:8321) After=network.target [Service] Type=simple # WorkingDirectory is deliberately NOT the repo. `-m http.server` puts the # working directory first on sys.path, and the repo ships selectors.py — so # serving the repo by sitting in it makes socketserver import ours instead of # the stdlib's and the unit crash-loops on # "module 'selectors' has no attribute 'SelectSelector'". # --directory serves the files without standing in them. WorkingDirectory=/ # The page is at http://127.0.0.1:8321/dashboard.html — refresher writes # dashboard.json into the same directory, both resolved off the package's own # __file__. # No --bind: the page is reachable from the LAN, not only from this box. # openbridge stays loopback-only, so a LAN viewer just falls back to opening a # new tab — progressive enhancement, and the page is never worse than it was. ExecStart=@VENV@/bin/python -m http.server 8321 --directory @REPO@ Restart=on-failure RestartSec=5 [Install] WantedBy=default.target