Es geht, UniFi Protect im Docker Container auf eigener ARM64 Hardware installieren!
Ich nutze das nicht produktiv, sondern erstmal nur in einer Testumgebung zum ausprobieren.
Diese Anleitung basiert auf https://github.com/markdegrootnl/unifi-protect-arm64.
Funktioniert, einige bugs, kommt aber leider nicht über die Version 3.1.16 heraus. (neue Images lassen sich nicht erstellen)
*** Neues Repository gefunden, siehe #2. ***
23.06.2024 - aktuellste Version: UniFi OS 3.1.16 mit UniFi Protect 2.8.35 (die 3.2.x lässt sich nicht erstellen) 24.09.2023 - Anleitung aktualisiert (neues Docker Image erstellen, 3.1.16)
mein Setup:
- Raspberry Pi 4 (4GB)
- Raspberry Pi OS Lite (64bit, Debian 11 Bullseye)
- 120GB SSD mit USB-Adapter (für Pi OS)
- 500GB SSD mit USB-Adapter (für storage)
- 2 Kameras (G3 Flex, G3 Micro)
Geht auch mit nur einer grossen SSD. Der Ordner /storage muss aber => 100GB sein, da sonst unifi-protect nicht startet.
Docker installieren
pi@nvr:~ $ curl -fsSL https://get.docker.com -o get-docker.sh pi@nvr:~ $ sudo sh get-docker.sh pi@nvr:~ $ docker -v Docker version 24.0.5, build ced0996
Den aktuellen Benutzer (nicht root) in die Docker Gruppe aufnehmen.
pi@nvr:~ $ sudo usermod -aG docker ${USER}
System vorbereiten
Problem mit systemd im Docker Container. (Failed to connect to bus: No such file or directory)
Am Ende der /boot/cmdline.txt diesen Kernel Parameter anhängen und neu starten.
systemd.unified_cgroup_hierarchy=0
SSD nach /storage einbinden. (Die Platte erscheint nach dem einstecken bei mir als /dev/sdb.)
Mit, z.B. cfdisk, die SSD löschen, eine Partition erstellen und diese dann mit ext4 formatieren.
pi@nvr:~ $ sudo mkdir /storage pi@nvr:~ $ sudo cfdisk /dev/sdb pi@nvr:~ $ sudo mkfs.ext4 /dev/sdb1
Die UUID der Festplatte ermitteln
pi@nvr:~ $ lsblk -f NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINT sda ├─sda1 vfat FAT32 bootfs 0B22-2966 224.3M 12% /boot └─sda2 ext4 1.0 rootfs 3ad7386b-e1ae-4032-ae33-0c40f5ecc4ac 24.9G 7% / sdb └─sdb1 ext4 1.0 81a19315-d7ff-4ef3-8367-e945dd06816a
und in die /etc/fstab eintragen, damit sie automatisch nach jedem reboot unter /storage eingebunden wird!
UUID=81a19315-d7ff-4ef3-8367-e945dd06816a /storage ext4 auto,nofail,sync,users,rw 0 0
Reboot und kontrollieren ob die Platte eingebunden ist. (erscheint jetzt als /dev/sda1)
pi@nvr:~ $ df -h Filesystem Size Used Avail Use% Mounted on /dev/root 28G 3.3G 24G 13% / devtmpfs 3.6G 0 3.6G 0% /dev tmpfs 3.9G 0 3.9G 0% /dev/shm tmpfs 1.6G 1.3M 1.6G 1% /run tmpfs 5.0M 4.0K 5.0M 1% /run/lock /dev/sda1 458G 40K 435G 1% /storage /dev/sdb1 255M 31M 225M 13% /boot tmpfs 782M 0 782M 0% /run/user/1000
Docker
Container erstellen und starten. (das Image kommt mit UNVR 3.1.14 und Protect 2.8.35)
docker run -d \ --name unifi-protect \ --privileged \ --tmpfs /run \ --tmpfs /run/lock \ --tmpfs /tmp \ --restart unless-stopped \ -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ -v /storage/srv:/srv \ -v /storage/data:/data \ -v /storage/persistent:/persistent \ --network host \ -e STORAGE_DISK=/dev/sda1 \ markdegroot/unifi-protect-arm64
Container läuft.
pi@nvr:~ $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ba511ed9ce27 markdegroot/unifi-protect-arm64 "/lib/systemd/systemd" 44 minutes ago Up 28 minutes unifi-protect
UniFi Protect
Über https://ip-addresse kann das WebUI gestartet werden.
Fehlersuche
Sollte die WebUI mal nicht erreichbar sein, in den Container wechseln.
pi@nvr:~ $ docker exec -it unifi-protect bash
Prüfen ob die Dienste laufen (ggf. neu starten) und die Ports offen sind.
Sollte die WebUI nicht laden oder Dienste nicht starten, den Container stoppen und den Ordner /storage/data löschen. (unifi-core)
Die unifi-protect Konfiguration bleibt erhalten. (/storage/srv, Kamera Settings und Recordings.)
Jetzt sollte sich das WebUI mit der Ersteinrichtung wieder zeigen. Das Problem hatte ich mehrmals und konnte mir damit helfen.
Updates
Updates lassen sich nicht über das WebUI installieren. Es muss ein neues Docker Image erstellt werden!
- 04.09.2023 – UniFi OS – Network Video Recorders 3.1.16
- aktuellere Versionen lassen sich nicht erstellen (dependency problems)
Neues Image erstellen.
auf dem Pi alles als root
sudo su
build Verzeichnis anlegen
mkdir /opt/build-unvr && cd /opt/build-unvr
benötigte Pakete installieren
apt install git binwalk dpkg-repack
unifi-protect-arm64 Git Repository klonen
git clone https://github.com/markdegrootnl/unifi-protect-arm64.git
UNVR4 Firmware herunterladen und entpacken
mkdir /opt/build-unvr/firmware && cd /opt/build-unvr/firmware wget -O fwupdate.bin https://fw-download.ubnt.com/data/unifi-nvr/5146-UNVR-3.1.16-923e980d-ab69-4884-b152-e68329b6a80a.bin binwalk -e fwupdate.bin
Paketliste erstellen
dpkg-query --admindir=_fwupdate.bin.extracted/squashfs-root/var/lib/dpkg/ -W -f='${package} | ${Maintainer}\n' | grep -E "@ubnt.com|@ui.com" | cut -d "|" -f 1 > packages.txt
deb Pakete neu erstellen (die warnings können ignoriert werden)
while read pkg; do dpkg-repack --root=_fwupdate.bin.extracted/squashfs-root/ --arch=arm64 ${pkg} done < packages.txt
die /usr/lib/version Datei aus der Firmware nach unifi-protect-arm64/put-version-file-here kopieren
cp -v _fwupdate.bin.extracted/squashfs-root/usr/lib/version ../unifi-protect-arm64/put-version-file-here/
einige deb Dateien aus der Firmware nach unifi-protect-arm64/put-deb-file-here kopieren (ubnt-archive-keyring, unifi-core, ubnt-tools, ulp-go, unifi-assets-unvr)
cp -v ubnt-archive-keyring* unifi-core* ubnt-tools* ulp-go* unifi-assets-unvr* ../unifi-protect-arm64/put-deb-files-here/
Änderungen im Dockerfile! (Fehlermeldungen beim docker build)
# fehlermeldung: debconf: delaying package configuration, since apt-utils is not installed + install apt-utils # fehlermeldung: sed: can't read /usr/share/unifi-core/app/config/config.yaml: No such file or directory - #&& sed -i 's/redirectHostname: unifi//' /usr/share/unifi-core/app/config/config.yaml \ # fehlermeldung: This script, located at https://deb.nodesource.com/setup_X, used to install Node.js is deprecated now and will eventually be made inactive. + neue Installationsroutine für Node.js (https://github.com/nodesource/distributions) # pull request (https://github.com/markdegrootnl/unifi-protect-arm64/pull/16/commits/4b915be6e13286ba44f2956b9d6dfd499cc6af52) + && chmod 666 /etc/timezone /etc/localtime
Bitte mein Dockerfile benutzen und das unifi-protect-arm64/Dockerfile ersetzen!
cd /opt/build-unvr/unifi-protect-arm64 curl -sL https://bachmann-lan.de/projects/unifi-protect-arm64/Dockerfile -o Dockerfile
neues Docker Image erstellen
docker build -t markdegroot/unifi-protect-arm64:3.1.16 .
Container aus neuem Image erstellen.
Docker Images auflisten.
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE markdegroot/unifi-protect-arm64 3.1.16 0f7d634890be 9 minutes ago 1.18GB markdegroot/unifi-protect-arm64 latest 333237f5ae00 4 weeks ago 1.28GB
Docker Container auflisten. (CONTAINER-ID kopieren)
$ docker container list CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 338743a93a57 markdegroot/unifi-protect-arm64 "/lib/systemd/systemd" About an hour ago Up About an hour unifi-protect
Docker Container stoppen.
$ docker stop unifi-protect unifi-protect
Docker Container löschen.
$ docker rm 338743a93a57 338743a93a57
Erst nachdem ich /storage/data gelöscht habe, startet der unifi-core Service im Container. (die Config des NVR geht verloren)
rm -r /storage/data
Docker Container aus neuem Image erstellen.
docker run -d \ --name unifi-protect \ --privileged \ --tmpfs /run \ --tmpfs /run/lock \ --tmpfs /tmp \ --restart unless-stopped \ -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ -v /storage/srv:/srv \ -v /storage/data:/data \ -v /storage/persistent:/persistent \ -v /etc/timezone:/etc/timezone:ro \ -v /etc/localtime:/etc/localtime:ro \ -e TZ=Europe/Berlin \ --network host \ -e STORAGE_DISK=/dev/sda2 \ markdegroot/unifi-protect-arm64:3.1.16
neuer Docker Container läuft
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a32a8aa7f9c7 markdegroot/unifi-protect-arm64:3.1.16 "/lib/systemd/systemd" 8 seconds ago Up 7 seconds unifi-protect
Da die Config weg ist, wird das Setup neu gestartet.
Update durchgeführt … ;)
Sonstiges
- der UNVR läuft bisher ohne Probleme mit den zwei Kameras
- alles OHNE einen Ubiquiti Account nutzbar (auch die Android Protect App)
- Fehler: die Storage Seite lädt nicht, keine Übersicht der Speichernutzung (bekanntes Problem)
- Fehler: System Config Backup funktioniert nicht
- Update: großer Aufwand und die Config des NVR geht verloren
- alles ziemlich frickelig …
Hi, I’m trying this on my pi5, but i cannott get the WEBUI to open,
dmesg no longer throw read only error after systemd.unified_cgroup_hierarchy=0 fix,
the only red error i see on dmesg is this but not sure if it related.
systemd-journald.service: Attaching egress BPF program to cgroup /sys/fs/cgroup/unified/system.slice/systemd-journald.service failed: Operation not permitted
The portainer doesnt show any logs either
secondly you mention checking the services, problem is, after pulling the first docker image none of the services existed for my case.
The github doesnt mention anything about services either. What am i missing?
Hard to say.
Which Version are you trying to install, UNVR 3.1.14?
Hi,
danke für die Doku, die ist super!
Ein Frage, bei mir auf dem rpi4 startet protect mit der Option “-v /sys/fs/cgroup:/sys/fs/cgroup:ro” nicht. Lasse ich diese weg, startet protect. Ich nutze Raspberry Pi OS 11 (64-bit), welche kommt bei dir zum Einsatz?
VG,
Michael
Bei mir ist es ein: Raspberry Pi OS Lite (64bit, bullseye)
Hi,
danke für deine Antwort (wer lesen kann… steht auch ganz oben; ich bl*). Habe 3.1.16 nun am rennen. Geht nun auch mit ohne cgroup Option.
Schicke dir die Tage noch ein Patch für Dockerfile, evtl. kann es der eine oder andere Gebrauchen :-)
Version 3.2.X habe ich bisher nicht am laufen, die Abhängigkeiten zu nginx in Debian 11 funktionieren noch nicht.
Hast du irgendeine 3.2er Version am laufen und wie hast du das mit den Abhängigkeiten hinbekommen?
VG
Bei mir läuft die 3.1.16. Update auf die 3.2.x steht noch aus. ;)
Also,
die 3.16 läuft auch super schon länger, aber das mit den 3.2 er geht einfach nicht. Image naja aber dann container geht einfach nicht. Hab schon viel probiert.
mfg
Auf dem Odroid M1S mit Ubuntu-Image startet die Protect-App mit der Fehlermeldung “Cannot read properties of null (reading ‘writeThroughput’)” ständig neu. Grund war, dass im Ubuntu-Kernel IO Accounting nicht konfiguriert ist. Es half, den Kernel mit den Optionen CONFIG_TASKSTATS, CONFIG_TASK_DELAY_ACCT und CONFIG_TASK_IO_ACCOUNTING neu zu bauen. Vermutlich geht alternativ auch das Debian-Image von Odroid. Vielleicht hilft das ja jemandem. :-)
Das 3.1.16-Image konnte ich dank deiner ausführlichen Anleitung nachbauen. Wenn ich es starte, leitet der Browser aber immer sofort auf http://unifi weiter, ich erreiche die Weboberfläche deshalb gar nicht. Mit dem alten markdegroot/unifi-protect-arm64:latest-Image funktioniert es. Hast du eine Idee, was ich falsch gemacht haben könnte? (Ich habe den Container mit leeren /storage-Verzeichnissen komplett neu aufgesetzt, kann also keine alte Konfiguration sein.)
Danke!
Vielen Dank für das tolle Image und die hervorragende Anleitung!
Mit “root@piprotect:/# unifi-protect ” gabs jeweils eine Fehlermeldung wie “Error: EACCES: permission denied, mkdir ‘/data/unifi-protect'”. Seltsam.
Docker hat von cgroups v1 zu cgroups v2 aktualisiert.
Das sollte wohl dann so starten:
docker run -d \
–name unifi-protect \
–privileged -v /sys/fs/cgroup:/sys/fs/cgroup:rw \
–tmpfs /run \
–tmpfs /run/lock \
–tmpfs /tmp \
–restart unless-stopped \
-v /sys/fs/cgroup:/sys/fs/cgroup:ro \
-v /storage/srv:/srv \
-v /storage/data:/data \
-v /storage/persistent:/persistent \
–network host \
-e STORAGE_DISK=/dev/sda1 \
markdegroot/unifi-protect-arm64
So. Jetzt muss ich nur noch rausfinden, warum der Webaccess nichts zeigt…