OTP Relay System Architecture

Click any box in the diagram to see a short explanation. This is standalone HTML for GitHub Pages; no dependencies required.

Interactive diagram
OTP Relay — full system architecture Flowchart showing fresh install, where all components live on the Pi, and the GitHub Actions update pipeline across four deployment lanes. Fresh install Where things live on the Pi GitHub → Pi update pipeline git clone into /opt/otp-relay sudo bash install.sh runs all 8 steps remove .git /opt/otp-relay becomes deploy-target install.sh provisions: apt packages python3, nginx, arping otprelay user system, no login python3 venv fastapi, uvicorn… nginx + TLS cert self-signed, 10yr systemd units otp-relay + monitor Edit .env SERVER_HOSTNAME · SERVER_IP · SMS_SECRET_TOKEN · PHONE_IP … setup_action-runner.sh register Pi as self-hosted runner start services systemctl start otp-relay/monitor /opt/otp-relay deploy-target · no .git main.py FastAPI app monitor.py ARP + WhatsApp frontend/ app.jsx · index.html frontend/help/ rendered docs data/ audit.log · users.xlsx venv/ python deps .env secrets · not in git · root:otprelay 640 /etc/systemd/system/ otp-relay.service otp-monitor.service /etc/nginx/ sites-available/otp-relay /etc/ssl/otp-relay/ server.crt · server.key ~/actions-runner/ push to main · GitHub changed paths trigger matching workflow self-hosted runner (Pi) checks out repo into _work/ app code main.py · monitor.py → restart services portal UI app.jsx · index.html → no restart help docs docs/help/** → build → rsync to frontend/help server config systemd · nginx → daemon-reload deploy_application _code.py deploy_portal _ui.py rsync --delete frontend/help/ → live deploy_server _config.py /opt/otp-relay/ files copied in — no git pull, no conflicts /etc/systemd/system/ · nginx sudo-gated · exact command allowlist deploy_users.sh hot-reload users.xlsx · no restart