09 - RouteTrack Pi — Dashboard Autostart (Gunicorn + systemd) Date: December 25, 2025 Category: Raspberry Pi / GPS / Flask / systemd Backlink: 08 – RouteTrack Pi — Local Web Dashboard (Flask API + Leaflet Map) Project Goal At this stage RouteTrack already has a working local web dashboard (Flask + Leaflet). This page productionizes that dashboard so it behaves like a real appliance: Starts automatically on boot Stays running in the background Restarts if it crashes Runs the Flask app using Gunicorn (production WSGI server) This is especially important because this Pi will be powered off frequently and used on-the-go. Why Gunicorn + systemd? Gunicorn Gunicorn is a production-grade Python WSGI server that runs Flask reliably with multiple workers. systemd systemd provides: Autostart on boot Automatic restart on failure Central logging via journalctl Clean service management ( start/stop/status ) Install Gunicorn (venv) Install into the existing RouteTrack virtual environment: /opt/routetrack/venv/bin/pip install gunicorn My output confirmed it was already installed: Requirement already satisfied: gunicorn in /opt/routetrack/venv/lib/python3.13/site-packages (23.0.0) Create the Dashboard systemd Service Create the service file: sudo nano /etc/systemd/system/routetrack-dashboard.service Paste the unit file: [Unit] Description=RouteTrack Local Dashboard (Gunicorn) After=network-online.target Wants=network-online.target [Service] # Run the service under my normal user (not root) User=zippyb Group=zippyb # Ensure relative paths work (app:app loads from this folder) WorkingDirectory=/opt/routetrack/web # Start Gunicorn on port 5000, listening on all interfaces # -w 2 = 2 worker processes (lightweight + responsive on Pi) ExecStart=/opt/routetrack/venv/bin/gunicorn -w 2 -b 0.0.0.0:5000 app:app # Keep it alive if it crashes Restart=always RestartSec=3 # Basic hardening NoNewPrivileges=true PrivateTmp=true [Install] WantedBy=multi-user.target Reload systemd and Enable the Service Reload units: sudo systemctl daemon-reload Enable + start the service: sudo systemctl enable --now routetrack-dashboard.service Verify the Service Is Running Check status: systemctl status routetrack-dashboard.service --no-pager -l My output confirmed it is running and listening properly: Service is active (running) Gunicorn started successfully Listening on http://0.0.0.0:5000 Two workers booted Example output: Active: active (running) Main PID: 9358 (gunicorn) Listening at: http://0.0.0.0:5000 (9358) Booting worker with pid: 9359 Booting worker with pid: 9360 Operational Notes Where logs are stored Because this is managed by systemd, logs are available via: journalctl -u routetrack-dashboard.service --no-pager -l Last 50 lines: journalctl -u routetrack-dashboard.service -n 50 --no-pager -l Accessing the dashboard From any device on the same network: http://:5000 Find the Pi’s IP: hostname -I Run On Demand (Manual Service Controls) Start: sudo systemctl start routetrack-dashboard.service Stop: sudo systemctl stop routetrack-dashboard.service Restart: sudo systemctl restart routetrack-dashboard.service Status: systemctl status routetrack-dashboard.service --no-pager -l Next Steps Now that the dashboard is always online, the next improvements will focus on making RouteTrack truly “truck ready”: Shift mode (Start Shift / End Shift buttons) Offline mapping options (for no cell coverage) Exports (GeoJSON/CSV) and backup strategy for on-the-go use