Files
zima-apps/Apps/snacks/README.md
T

143 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Snacks
Automated video library encoder with hardware acceleration (NVENC, QSV, VAAPI, AMF).
## Purpose
Snacks batch-transcodes video libraries using FFmpeg with hardware acceleration.
It monitors directories, skips already-encoded files, retries with fallbacks, and supports distributed cluster encoding across multiple ZimaOS nodes.
## Port
- `6767/tcp` — Web UI at `http://localhost:6767`
## Volumes
| Host path | Container path | Description |
|---|---|---|
| `/DATA/AppData/$AppID/media` | `/app/work/uploads` | Media library — source files to encode |
| `/DATA/AppData/$AppID/logs` | `/app/work/logs` | Transcoding logs |
| `/DATA/AppData/$AppID/config` | `/app/work/config` | Settings and SQLite database |
## Hardware Acceleration
Snacks uses GPU encoding via `/dev/dri`:
| Driver | Codecs | Devices |
|---|---|---|
| VAAPI (Linux) | H.265, H.264 | Intel iHD/i965, AMD VAAPI |
| QSV (Intel) | H.265, H.264 | Intel Quick Sync Video |
| NVENC (NVIDIA) | H.265, H.264 | NVIDIA GPUs via CUDA |
| AMF (AMD) | H.265, H.264 | AMD GPUs |
Auto-detection runs on first encode and picks the best available encoder.
## Cluster Mode
Snacks supports distributed encoding across multiple ZimaOS nodes.
- Nodes discover each other via UDP broadcast on the LAN
- One instance acts as coordinator; others are workers
- Jobs are assigned automatically; failed nodes are re-assigned
- A shared secret authenticates intra-cluster communication
**UDP broadcast requirement**: Cluster mode requires `network_mode: host` — bridge mode blocks LAN broadcast discovery, making nodes invisible to each other.
## Health Check
`http://localhost:6767/Home/Health` — returns HTTP 200 when the backend is ready.
## Privilegier och säkerhet
Aktiva säkerhetsinställningar i denna app:
- `security_opt: ["no-new-privileges:true"]`
- `cap_drop: ["ALL"]`
- `privileged: true`
- `network_mode: host`
- Device mount: `/dev/dri:/dev/dri`
Motivering:
- `no-new-privileges:true` och `cap_drop: ["ALL"]` kompenserar med lägsta möjliga capability-yta.
- Isolerad data-path under `/DATA/AppData/$AppID/...`.
## Säkerhetsavvikelser
### 1. `network_mode: host`
**Varför det behövs:**
- Snacks cluster nodes discover each other via UDP broadcast on the local network.
- Bridge mode only forwards unicast traffic; broadcast packets never reach other nodes.
- Without host networking, cluster mode is non-functional.
**Alternativ som utvärderats:**
- Bridge mode with port exposure: broadcasts are not forwarded by the Docker bridge.
- Static IP configuration: requires manual node addressing and is error-prone.
- Multicast DNS (mDNS): not supported by Docker bridge in all deployments.
**Risker:**
- Container has full access to all host ports.
- No network isolation between Snacks and other services on the host.
- If the container is compromised, the attacker has host network access.
**Riskreducering:**
- `cap_drop: ["ALL"]` minimizes syscall surface.
- `no-new-privileges:true` prevents privilege escalation.
- No sensitive host directories are mounted beyond the app-specific volumes.
---
### 2. `privileged: true`
**Varför det behävs:**
- `/dev/dri` (Direct Rendering Infrastructure) is required for VAAPI/QSV hardware acceleration.
- On standard Linux, this device is accessible without privileged mode if the user is in the `video` or `render` group.
- ZimaOS does not reliably provide these groups in the container runtime context, making `privileged: true` the only reliable way to grant device access.
**Alternativ som utvärderats:**
- `security_opt: ["apparmor:..."]` with specific `/dev/dri` access: not reliably portable across ZimaOS kernel configurations.
- Pre-create device nodes with specific permissions: does not work dynamically when the device appears.
- Skip hardware acceleration (software encoding only): defeats the primary purpose of the app.
**Risker:**
- Container has full root capabilities on the host.
- If container is compromised, attacker has theoretical access to all host resources.
- Hardware acceleration devices can be accessed directly.
**Riskreducering:**
- `cap_drop: ["ALL"]` drops all capabilities even when privileged.
- Only the specific `/dev/dri` device is mounted; no other host devices.
- Data volumes are scoped to `/DATA/AppData/$AppID/...`.
---
### 3. Device mount: `/dev/dri:/dev/dri`
**Varför det behövs:**
- VAAPI and QSV hardware encoding require direct access to the GPU render nodes in `/dev/dri`.
- Without this mount, FFmpeg falls back to software encoding which is 1050x slower on 4K content.
**Alternativ som utvärderats:**
- Specific device nodes (e.g., `/dev/dri/renderD128`): device names can vary by driver version and host kernel.
- No hardware acceleration: software fallback is too slow for practical use.
**Risker:**
- The container can enumerate and use all graphics devices on the host.
- On multi-user systems, other users' GPU resources may be accessible.
**Riskreducering:**
- `privileged: true` combined with `cap_drop: ["ALL"]` ensures the container cannot load additional kernel modules or escalate privileges.
- Only the render nodes are exposed; no other host devices are passed through.