On-site box
Displays poll this machine. Give it a DHCP reservation, keep it on, and do not forward port 8090 to the internet.
A Docker Compose stack: the Dutywall panel/renderer, optional MediaMTX for live cameras, and a data volume. It serves:
| URL | Who |
|---|---|
http://<LAN-IP>:8090/ | Admin panel (browser login) |
/player | Real screen: enroll code if it has no id |
/player?demo=1 | Smoke test, no enroll |
/roku-config.json | What every display polls |
/healthz | standalone or managed |
| Minimum | Comfortable | |
|---|---|---|
| CPU | 2 cores (x86_64 or Pi 4/5) | 4 cores if you remux YouTube or several cameras |
| RAM | 4 GB | 8 GB |
| Disk | 16 GB | SSD; Pi prefers USB SSD over SD for the data volume |
| Network | Same L2/L3 as the screens | Static DHCP lease for this host |
Platform steps: Linux · Windows · Raspberry Pi · macOS
Copy .env.standalone.example to .env. The helper scripts fill the LAN IP; you still set a real panel password.
| Variable | What to put |
|---|---|
DUTYWALL_BASE_URL | http://<this-machine-LAN-IP>:8090, the address screens will use, not localhost |
DUTYWALL_PANEL_USER / PASSWORD | Panel login. Default password changeme is refused |
DUTYWALL_LAT / LON / RADAR_SITE | Your site. Radar is K + 3 letters (e.g. KMRX) |
DUTYWALL_NWS_UA | App name + a real email; NWS requires it |
DUTYWALL_ALERT_TOKEN | Optional long random string to enable the panic webhook |
DUTYWALL_CLOUD_URL / SITE_ID / SITE_TOKEN | Optional. Paste from the cloud panel. Blank = air-gap |
curl -sS http://127.0.0.1:8090/healthz
# {"ok":true,"mode":"standalone"} or "managed" if cloud env is set
Open the panel, then enroll screens. Keep :8090 on the LAN only.
docker compose --profile camera up -d
Linux (including Pi as box) can use host networking, best for RTSP over VPN/WireGuard. Windows and macOS Docker Desktop publish MediaMTX ports instead; LAN cameras Docker can route to still work.
On a connected build machine: ./scripts/package-standalone.sh --with-image. Copy the tarball, docker load -i dutywall-image.tar, start compose without --build. Video, slideshows, panic, and enrollment work offline. NWS will not update without HTTPS to api.weather.gov.
The volume dutywall-data is the site (inventory, media, schedules). Upgrade by replacing the files and docker compose up -d --build. The volume stays. Stop with docker compose down (volume is kept).