Background
bin/install.sh is currently hard-coded to refuse anything other than Raspberry Pi 2/3/4-64/5 or x86. That's narrower than the actual capability of the stack — most of Anthias is distro- and SoC-agnostic Linux + Docker — but the device-detection step bails before the rest gets a chance.
Goal: add best-effort support for generic 64-bit ARM SBCs running Armbian (Orange Pi, Rock Pi, Banana Pi, etc.). "Best-effort" because hardware video decode varies per chipset; we'd ship a fallback that works everywhere, with hooks for per-SoC polish later.
Audit: where the Pi-isms actually live
| Location |
What |
Real blocker? |
bin/install.sh:254-269 set_device_type |
hard-codes Raspberry Pi N regex on /proc/device-tree/model, exits otherwise |
yes — installer bails first |
ansible/site.yml:19 |
asserts device_type in ['pi2','pi3','pi4-64','pi5','x86'] |
yes — same bail |
ansible/roles/system/tasks/docker.yml |
docker_arch_by_device_type map |
needs an entry for new device_types |
docker-compose.yml.tmpl:22, 87 |
/dev/vchiq device passthrough (Pi-only Broadcom VPU IPC) |
minor — bin/upgrade_containers.sh:87 already strips it for x86|pi5, just extend the regex |
ansible/roles/system/tasks/boot.yml |
writes /boot/firmware/{config,cmdline}.txt, sets gpu_mem_*, dtoverlay=vc4-kms-v3d, [pi4] |
already gated by the raspberry-pi ansible tag; install.sh:292 skips it for x86. Same skip extends to non-Pi ARM. |
Image registry (ghcr.io/screenly/anthias-{server,viewer,redis}:${TAG}-${DEVICE_TYPE}) |
per-board image tags built in CI |
new device_type → new published image tag |
webview/Dockerfile Qt 5 cross-build |
depends on libraspberrypi0 (Broadcom userland) |
only relevant for pi2/pi3 (Qt 5 path). arm64 boards run Qt 6 against standard DRM/KMS — no Pi-specific deps |
What's not Pi-specific (works on Armbian as-is)
- Django/Celery/Redis stack, the REST API, the frontend, the install-time playbook flow, user/group setup.
network role: NetworkManager + polkit, distro-version-aware but not Pi-specific.
- Viewer container is
privileged: true, so /dev/dri/* passes through and Mesa DRM/KMS Just Works for any board with a mainline driver (Mali via panfrost/panthor, Lima, Etnaviv, Adreno).
- ALSA, systemd, cgroups, filesystem layout — identical on Armbian.
The one genuinely hard part: hardware video decode
The viewer relies on GStreamer + V4L2-M2M plugins for hardware-accelerated H.264/H.265. Plugins differ per chipset:
- Pi →
rpivid (Pi kernel + firmware).
- Rockchip RK3568/3588 (Rock 5, Orange Pi 5) →
rkmpp.
- Allwinner H6/H616 →
cedrus (V4L2-M2M, mainline).
- Amlogic →
meson-vdec.
Without the right plugin, the viewer falls back to software decode: fine at 720p, stutter-prone at 1080p, pegs CPU at 4K. A "generic-arm64" image works for low-res signage but isn't ideal as a daily-driver for video walls.
Tiered scope
Tier 1 — generic-arm64 ("it boots, software-decoded video"). ~1-2 days.
Single PR, contained changes:
After Tier 1, an Armbian user can bash <(curl -sL https://install-anthias.srly.io), the installer recognizes the board, the playbook runs, and the stack comes up. Video plays via software decode.
Tier 2 — per-SoC video decode. Weeks not days.
- Per-SoC viewer image variants with the right GStreamer plugins.
- Test matrix for the popular boards.
- Per-board image tags (
rk3588, rk3568, allwinner-h6, …).
Tier 3 — first-class.
- Rolling Armbian builds in CI.
- Pi-Imager-style installer image with cloud-init.
Open question for Tier 1: pre-built image vs build-on-device
Two ways to ship the generic-arm64 viewer/server image:
- Publish in CI — same as the existing pi5/pi4-64 builds. Real cost: an extra arm64 build matrix entry, ~5-10 min per build, plus the GHCR storage. Best UX: install completes without waiting on a local build.
- Build on the device (
MODE=build) — bin/upgrade_containers.sh already supports it. Slower install (~30-60 min on an Orange Pi 5 building the viewer), but zero ongoing CI cost until a board is popular enough to warrant it.
Decision is partly philosophy (do we commit CI bandwidth to "best-effort" before validating demand?) and partly practical (image_builder's QEMU-emulated arm64 build vs the GitHub Actions arm64 runner availability). Worth deciding before opening the PR.
Acceptance criteria for Tier 1
- A fresh
bash <(curl -sL https://install-anthias.srly.io) install on an Armbian aarch64 board (Orange Pi 5 or similar) completes the playbook without Pi-specific tag failures.
- The Anthias web UI is reachable.
- An H.264 1080p test video plays end-to-end (software decode acceptable).
- Existing Pi installs (pi5/pi4-64/pi3/pi2) and x86 installs are unaffected — same image tags, same device-type detection, same playbook.
Background
bin/install.shis currently hard-coded to refuse anything other than Raspberry Pi 2/3/4-64/5 or x86. That's narrower than the actual capability of the stack — most of Anthias is distro- and SoC-agnostic Linux + Docker — but the device-detection step bails before the rest gets a chance.Goal: add best-effort support for generic 64-bit ARM SBCs running Armbian (Orange Pi, Rock Pi, Banana Pi, etc.). "Best-effort" because hardware video decode varies per chipset; we'd ship a fallback that works everywhere, with hooks for per-SoC polish later.
Audit: where the Pi-isms actually live
bin/install.sh:254-269set_device_typeRaspberry Pi Nregex on/proc/device-tree/model, exits otherwiseansible/site.yml:19device_type in ['pi2','pi3','pi4-64','pi5','x86']ansible/roles/system/tasks/docker.ymldocker_arch_by_device_typemapdocker-compose.yml.tmpl:22, 87/dev/vchiqdevice passthrough (Pi-only Broadcom VPU IPC)bin/upgrade_containers.sh:87already strips it forx86|pi5, just extend the regexansible/roles/system/tasks/boot.yml/boot/firmware/{config,cmdline}.txt, setsgpu_mem_*,dtoverlay=vc4-kms-v3d,[pi4]raspberry-piansible tag;install.sh:292skips it for x86. Same skip extends to non-Pi ARM.ghcr.io/screenly/anthias-{server,viewer,redis}:${TAG}-${DEVICE_TYPE})webview/DockerfileQt 5 cross-buildlibraspberrypi0(Broadcom userland)What's not Pi-specific (works on Armbian as-is)
networkrole: NetworkManager + polkit, distro-version-aware but not Pi-specific.privileged: true, so/dev/dri/*passes through and Mesa DRM/KMS Just Works for any board with a mainline driver (Mali via panfrost/panthor, Lima, Etnaviv, Adreno).The one genuinely hard part: hardware video decode
The viewer relies on GStreamer + V4L2-M2M plugins for hardware-accelerated H.264/H.265. Plugins differ per chipset:
rpivid(Pi kernel + firmware).rkmpp.cedrus(V4L2-M2M, mainline).meson-vdec.Without the right plugin, the viewer falls back to software decode: fine at 720p, stutter-prone at 1080p, pegs CPU at 4K. A "generic-arm64" image works for low-res signage but isn't ideal as a daily-driver for video walls.
Tiered scope
Tier 1 —
generic-arm64("it boots, software-decoded video"). ~1-2 days.Single PR, contained changes:
bin/install.sh::set_device_type— add a fallback branch:uname -m == aarch64and no Pi-string match →DEVICE_TYPE=generic-arm64.ansible/site.yml:19— addgeneric-arm64to the validated set.ansible/roles/system/tasks/docker.yml— addgeneric-arm64: arm64todocker_arch_by_device_type.bin/install.sh:292— extend the--skip-tags raspberry-pibranch to also skip ongeneric-arm64.bin/upgrade_containers.sh:87— extend the vchiq-strip regex from^(x86\|pi5)$to^(x86\|pi5\|generic-arm64)$.tools/image_builder/__main__.py— add ageneric-arm64build target. Effectively a thinner pi5 variant (Qt 6, arm64, nolibraspberrypi0, no Broadcom userland).ghcr.io/screenly/anthias-{server,viewer,redis}:latest-generic-arm64.After Tier 1, an Armbian user can
bash <(curl -sL https://install-anthias.srly.io), the installer recognizes the board, the playbook runs, and the stack comes up. Video plays via software decode.Tier 2 — per-SoC video decode. Weeks not days.
rk3588,rk3568,allwinner-h6, …).Tier 3 — first-class.
Open question for Tier 1: pre-built image vs build-on-device
Two ways to ship the
generic-arm64viewer/server image:MODE=build) —bin/upgrade_containers.shalready supports it. Slower install (~30-60 min on an Orange Pi 5 building the viewer), but zero ongoing CI cost until a board is popular enough to warrant it.Decision is partly philosophy (do we commit CI bandwidth to "best-effort" before validating demand?) and partly practical (image_builder's QEMU-emulated arm64 build vs the GitHub Actions arm64 runner availability). Worth deciding before opening the PR.
Acceptance criteria for Tier 1
bash <(curl -sL https://install-anthias.srly.io)install on an Armbian aarch64 board (Orange Pi 5 or similar) completes the playbook without Pi-specific tag failures.