# WeBrake ☕ A self-hosted web UI for [HandBrake CLI](https://handbrake.fr/features.php), built to run inside an **Alpine Linux LXC** on Proxmox. Upload media from any PC on your network, remux or re-encode it with the full range of HandBrake options (hardware encoders included when a GPU is passed through), watch live progress bars, and download the results straight back to the uploading machine. Cream-and-gold by day, dark-roast by night. ## One-liner install Run this **inside an existing Alpine LXC** (as root). It never runs on, or installs anything from, the Proxmox host: ```sh wget -qO- https://gogs.av2x.dev/av2x/WeBrake/raw/main/install.sh | ash ``` The installer will: 1. Enable the Alpine `community` repo and `apk add` Python 3, Flask, HandBrakeCLI, and VA-API driver packages. 2. Pull `app.py`, `index.html`, and `update.sh` from this repository into `/opt/webrake`. 3. **Generate a local `token.json`** containing the API token and Flask secret. This file is created on the container at install time — it is never pulled from the repo and must never be committed to it (`.gitignore` enforces this). 4. Register and start an OpenRC service (`rc-service webrake start`, enabled at boot). When it finishes it prints the URL (default port `8090`) and the API token. Paste the token into the UI once; it is remembered by your browser. ## Updating ```sh /opt/webrake/update.sh ``` The updater pulls fresh `app.py` and `index.html` (and itself) directly from the repo, keeps a `.bak` of the previous versions, leaves `token.json` untouched, and restarts the service. Nothing changes unless the repo copies differ. ## GPU passthrough (Proxmox host → LXC) WeBrake itself installs nothing on the host, but hardware encoding requires the host to expose the GPU device nodes to the container. On the **Proxmox host**, edit `/etc/pve/lxc/.conf`: **Intel / AMD (VA-API, QSV):** ``` dev0: /dev/dri/renderD128,gid=44 ``` (or on older Proxmox versions:) ``` lxc.cgroup2.devices.allow: c 226:* rwm lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir ``` **NVIDIA (NVENC):** ``` lxc.cgroup2.devices.allow: c 195:* rwm lxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file lxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file lxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file ``` Restart the container afterwards. WeBrake auto-detects `/dev/dri` and `/dev/nvidia*`, shows the result in the header badge, and marks hardware encoders (⚡ `nvenc_*`, `qsv_*`, `vce_*`) in the encoder list. If no GPU is visible it falls back to software encoders and tells you so. ## Using it 1. Open `http://:8090` and enter the API token. 2. Drag a video into the drop zone — the upload has its own progress bar and lands in `/var/lib/webrake/uploads`. 3. Optionally **Scan** the source to list its resolution, audio, and subtitle tracks. 4. Configure the encode across the tabs — General (container, chapters, ranges), Video (encoder, RF/bitrate, presets/tune/profile/level, framerate), Dimensions (resize, crop, anamorphic, rotate, pad), Filters (deinterlace, decomb, detelecine, denoise, sharpen, deblock, colorspace, grayscale), Audio (tracks, encoders, mixdown, DRC, gain, passthru masks), and Subtitles (selection, burn-in, forced, external SRT). 5. Anything not covered by a control is still available: the **Advanced** tab appends raw `HandBrakeCLI` arguments verbatim, so every flag in the [CLI reference](https://handbrake.fr/docs/en/latest/cli/command-line-reference.html) works. 6. Queue the encode. Jobs run one at a time with a live gold progress bar, fps, average fps, ETA, pass counter, full log viewer, and the exact command line used. 7. When a job is **done**, hit **Download** to pull the file back to the PC you're browsing from. Cancel and delete work as expected; deleting a job also removes its output and log. ## Files & layout | Path | Purpose | |---|---| | `/opt/webrake/app.py` | Flask backend (pulled from repo) | | `/opt/webrake/index.html` | Web UI (pulled from repo) | | `/opt/webrake/update.sh` | Updater (pulled from repo) | | `/opt/webrake/token.json` | **Local secrets — generated at install, never in the repo** | | `/var/lib/webrake/uploads` | Uploaded sources | | `/var/lib/webrake/output` | Finished encodes | | `/var/lib/webrake/logs` | Per-job HandBrake logs | | `/etc/init.d/webrake` | OpenRC service | Environment overrides: `WEBRAKE_PORT` (default `8090`), `WEBRAKE_DATA`, `WEBRAKE_REPO` (alternate raw-file base URL for install/update). ## Notes & limits - Uploads are capped at 64 GiB per file. - One encode runs at a time; the rest wait in the queue (HandBrake saturates the machine anyway). - The API token gates every endpoint. If you expose WeBrake beyond your LAN, put it behind HTTPS (reverse proxy) — the token travels in a header. - "Remuxing" without re-encoding: set audio encoder to `copy`, add `--audio-copy-mask` for the codecs to pass through, and pick a fast video path — or drive it entirely from the Advanced tab. ## License / repo Source of truth: