---
url: /de/install/proxmox.md
---

# Proxmox

camera.ui läuft auf Proxmox VE in einem LXC-Container, der Docker beherbergt. Ein Befehl auf dem Proxmox-Host richtet alles ein: Container, Docker und camera.ui.

::: tip Warum ein LXC und keine VM?
Ein LXC kann die iGPU **teilen**: `/dev/dri` bleibt gleichzeitig für den Host und andere Container nutzbar, während eine VM mit PCIe-Passthrough die GPU monopolisiert, und ein LXC hat weniger Overhead. Für NVIDIA-Karten ist eine VM die bessere Wahl (siehe unten).
:::

## Schnellstart

Auf dem Proxmox-Host (als root) ausführen:

```bash
curl -fsSLO https://raw.githubusercontent.com/cameraui/docker/main/proxmox/install-cameraui-lxc.sh
bash install-cameraui-lxc.sh
```

Das Script lädt das Ubuntu-24.04-LXC-Template, erstellt einen **unprivilegierten** Container mit Nesting (privilegierte Container können auf aktuellen Proxmox-Versionen Dockers AppArmor-Profil nicht mehr laden), installiert Docker darin, deployt camera.ui via Docker Compose und gibt die URL der Web-UI aus. Getestet mit Proxmox VE 9.

Umgebungsvariablen:

| Variable | Default | Bedeutung |
|---|---|---|
| `CTID` | nächste freie ID | Container-ID |
| `CT_HOSTNAME` | `cameraui` | Container-Hostname |
| `CORES` / `RAM_MB` / `DISK_GB` | `4` / `4096` / `16` | Container-Ressourcen |
| `BRIDGE` | `vmbr0` | Netzwerk-Bridge (Container bekommt seine IP per DHCP) |
| `STORAGE` | auto-detect | rootfs-Storage (bevorzugt `local-lvm`, `local-zfs`, `local`, sonst den ersten aktiven Storage, der ein Container-rootfs aufnehmen kann) |
| `TEMPLATE_STORAGE` | `local` | Storage, auf den das LXC-Template geladen wird (braucht Content-Typ „Container-Template“) |
| `FLAVOR` | `cpu` | `cpu`, `intel` oder `amd` (wählt den [Image-Flavor](/de/install/docker#hardware-beschleunigung)); `nvidia` ist [experimentell](#nvidia-im-lxc-experimentell) |
| `GPU_PASSTHROUGH` | `1` wenn Flavor ≠ cpu | reicht `/dev/dri` in den Container |
| `TZ` | Zeitzone des Hosts | Zeitzone im Container |

Beispiel für eine Intel-Maschine: `FLAVOR=intel bash install-cameraui-lxc.sh`

## Shell im Container öffnen

Das Script legt den Container ohne Root-Passwort an, über die Proxmox-Konsole oder SSH kommst du also nicht hinein. Von der Shell des Hosts:

```bash
pct enter <CTID>
```

Einzelne Befehle:

```bash
pct exec <CTID> -- docker logs cameraui
```

Konsole und SSH funktionieren, sobald du ein Passwort vergibst:

```bash
pct exec <CTID> -- passwd
```

## Hardware-Beschleunigung

* **Intel / AMD iGPU.** `FLAVOR=intel` (oder `amd`) setzen. Das Script reicht den GPU-Render-Node durch den Container bis zu Docker, sonst ist nichts zu konfigurieren. Details: [Hardware-Beschleunigung](/de/install/hardware-acceleration).
* **NVIDIA.** Nutze eine **VM mit PCIe-Passthrough** statt eines LXC. Darin folgst du dem Standard-[Docker-Setup](/de/install/docker) mit dem `nvidia`-Flavor. Ein LXC müsste Host-Treiber und Userspace-Bibliotheken im Container dauerhaft versionsgleich halten. Die VM monopolisiert dafür die Karte. Brauchen andere Dienste auf dem Host dieselbe GPU (Ollama, Jellyfin), siehe [NVIDIA im LXC](#nvidia-im-lxc-experimentell) unten.
* **KI-Beschleuniger (Coral, Hailo).** Den [Host-Treiber](/de/install/hardware-acceleration#host-prüfen) auf dem Proxmox-Host installieren, dann den Device-Node (`/dev/apex_0`, `/dev/hailo0`) in den Container reichen.

### NVIDIA im LXC (experimentell)

`FLAVOR=nvidia` teilt die Karte zwischen dem Container und anderen Diensten auf dem Host, was eine VM nicht kann. Der Haken ist eine harte Versionskopplung: Die NVIDIA-Userspace-Bibliotheken im Container müssen exakt zum Kernel-Treiber des Hosts passen, nach jedem Treiber-Update.

Voraussetzung ist ein funktionierender NVIDIA-Treiber auf dem Proxmox-Host (`.run`-Installer mit `--dkms` plus `pve-headers`; `nvidia-smi` auf dem Host muss funktionieren), und die installierte Treiberversion muss auf `download.nvidia.com` existieren. Dann:

```bash
FLAVOR=nvidia bash install-cameraui-lxc.sh
```

Das Script reicht alle `/dev/nvidia*`-Device-Nodes in den Container, installiert den passenden Userspace-Treiber (`--no-kernel-module`) plus das NVIDIA Container Toolkit (mit `no-cgroups=true`, weil ein unprivilegierter Container keine Device-Cgroups verwalten kann) und registriert einen Sync-Service, der nach Host-Treiber-Updates beim Boot den passenden Userspace nachinstalliert. Verifizieren mit:

```bash
pct exec <CTID> -- docker exec cameraui nvidia-smi
```

::: warning Experimentell
Dieser Weg hängt an NVIDIAs Installer-Archiv und daran, dass der Host-Treiber gesund bleibt; nach einem Host-Treiber-Update braucht der Container einen Reboot zum Nachsynchronisieren. Wenn es bricht, funktioniert der VM-Weg immer. Reports und Fixes sind im [docker-Repo](https://github.com/cameraui/docker) willkommen.
:::

## Aufnahmen auf einer dedizierten Platte oder einem NAS

Aufnahmen landen standardmäßig auf dem eigenen Volume des Containers. Für eine größere Platte, ein NAS-Share oder einen zusammengefassten Pool reichst du diesen Speicher in den Container und setzt den NVR-Speicherpfad darauf.

Unprivilegierte Container können NFS/CIFS-Shares nicht selbst mounten. Mounte das Share auf dem **Proxmox-Host** und reiche es als Mountpoint in den Container:

```bash
pct set <CTID> -mp0 /mnt/nas/recordings,mp=/mnt/recordings
```

Setze dann den NVR-**Speicherpfad** auf `/mnt/recordings` (Einstellungen → Aufnahmen → Speicher), oder siehe den [Speicher-Abschnitt](/de/install/docker#speicher-für-aufnahmen) der Docker-Seite.

::: warning FUSE-Mounts (mergerfs, rclone) brauchen Sonderbehandlung
Ein FUSE-Mount (etwa ein **mergerfs**-Pool, der mehrere Platten zusammenfasst) propagiert **nicht** wie ein normales Dateisystem in einen (unprivilegierten) Container. Ist der FUSE-Mount nicht **vor dem Container-Start** auf dem Host aktiv, sieht der Container den leeren Mountpoint auf der Root-Disk des Hosts statt den Pool. Aufnahmen landen dann auf der kleinen OS-Platte und werden innerhalb von Minuten wieder rotiert.

Mounte den Pool auf dem Host **vor** dem Container-Start (z.B. per fstab-Eintrag oder systemd-Unit mit `Before=pve-container@<CTID>.service`) und stelle sicher, dass der Mount in den Container geteilt wird. Danach immer **aus dem Container heraus verifizieren**.
:::

## Speichergröße verifizieren

Nach dem Setzen eines eigenen Speicherpfads prüfen, ob der Container das volle Volume sieht:

```bash
pct exec <CTID> -- df -h /mnt/recordings
```

Die angezeigte Größe muss zu deiner echten Platte oder deinem Pool passen. Zeigt sie die kleine Container-Root-Größe, ist der Mount nicht propagiert. Der NVR loggt seinen aufgelösten Speicher samt Größe außerdem bei jedem Start und zeigt in **Einstellungen → Aufnahmen** eine Warnung, wenn das Volume unerwartet klein ist.

## Verifizieren

Bei jedem Start loggt der Container, welche Devices tatsächlich angekommen sind. Siehe [Aus dem Container verifizieren](/de/install/hardware-acceleration#aus-dem-container-verifizieren). Die camera.ui-UI ist unter `https://<container-ip>:3443` erreichbar (das Script gibt die IP am Ende aus).
