Project · Home server
Xenticorp-4 Server
A self-hosted media stack fed by my own DVD and Blu-ray rips. It lives on X4, a bench-built Ubuntu server, and the ripping and encoding automation around it is still being built.
Work in progress. X4 and this page are both still being built, so the plans below will change as they turn into hardware and code.
Sorted by status: Running now Planned Ideas
Running now
Running nowCurrent setup
| Host | X4: Ubuntu server, bench build, reachable remotely over Tailscale |
|---|---|
| Containers | Docker: Jellyfin, ErsatzTV, Portainer, cloudflared |
| Media server | Jellyfin with Movies, TV Shows and Music libraries, exposed through a Cloudflare Tunnel |
| Live TV | ErsatzTV: custom channels and schedules built from my own library |
| Music | Jellyfin as a Spotify replacement: a Spotify playlist ripped to MP3 with CSVMusic to match the existing MP3 library |
| Dashboard | My own control dashboard for X4: service status and restarts, Jellyfin stats, importer status, system health, updates and power. Private, behind a login |
| Storage | NVMe for the OS and Jellyfin config; a 2.0 TB external drive for media |
| Ripping | MakeMKV on a laptop for now; moving it to X4 is planned. Tried ARM (Automatic Ripping Machine) and dropped it; building my own instead |
| Encoding | HandBrake on X1, software x265 |
| Output | MKV with soft subtitles (not burned in) and multiple audio tracks |
| Old host | Jellyfin, ErsatzTV and the cloudflared connector moved over from X2, whose copies are retired |
Hardware
| CPU / board / RAM | i5-10400F, MSI MAG Z490 Tomahawk, 32 GB DDR4 (reused from an old rig) |
|---|---|
| GPU | GT 1030, for display only (no hardware encoder) |
| PSU | Corsair CX650M |
| Storage | ~250 GB NVMe + 2 TB Seagate external |
No hardware encoding on X4. The 10400F has no integrated graphics (so no Quick Sync) and the GT 1030 has no NVENC, so every encode is CPU x265.
How media gets onto X4
How a website change goes live
Planned
Decided, not builtRip-to-library pipeline
Naming is handled by Ripnamer. A few lessons borrowed from Riparr:
- Ripping and encoding are separate stages, so the drives never wait on an encode.
- Only finished files get moved into the library (an atomic move), so Jellyfin never sees a partial file.
- Remember what’s already been ripped (a disc fingerprint) and skip duplicates.
- For TV, correct disc 1 and let the later discs cascade from it (an idea for Ripnamer).
- MakeMKV’s beta key expires monthly, so check and refresh it automatically.
Encoding: one shared queue (Tdarr)
- A Tdarr server on X4 in Docker, with worker nodes on X4 and X1. Each node pulls the next job it’s allowed to take from one shared queue.
- X4 is the always-on box. I turn X1 on for big ripping sessions; big jobs simply wait in the queue until it’s up.
- Rips over roughly 35 GB (threshold still to be settled) are tagged so only X1 takes them; X4 handles the smaller ones. The queue runs largest-first, so X1 grabs the big jobs and then helps with the rest.
- X1 runs two slots, one for small jobs and one for big. A big job can start next to a running small one, and a helper script keeps the small slot closed until the big job is done.
- CPU x265 everywhere, no NVENC: smaller files matter more than speed, and the TV library is where the storage goes.
Optical drive bay (1U)
Only ever two drives:
| Bay 1 | LG BU40N (9.5 mm slim) for 4K UHD. Slim SATA to an ATAPI-capable USB bridge (or SATA direct). |
|---|---|
| Bay 2 | The current 8-in-1 USB Blu-ray drive (hub and card reader combo) for DVD and regular Blu-ray, on a USB extension to X4’s rear port. |
- Enclosed front panel with the drive faces flush; the rest of the 1U stays open, no fan needed.
- Drives sit on printed shelves, tied to the rear posts or gusseted so pushing a tray doesn’t pry the panel.
- The BU40N screws in through its side M2 holes; the 8-in-1 is held with side lips and a strap.
- The 8-in-1’s top LED is rerouted to the panel with 1–2 mm PMMA fiber.
- Pinhole access for emergency eject.
- Printed in PETG/ASA, not PLA, and the panel can be split and assembled.
4K UHD is a drive decision, not a setting. It only works through MakeMKV LibreDrive on specific drives and firmware, so the plan is to check LibreDrive status in MakeMKV the day the drive arrives, and return it if it isn’t supported.
Control and alerts
One control service on X4 does the real work, with Discord, ntfy and Claude as front ends, so I can check on rips and get a ping on my phone when a disc needs swapping or something fails. The Claude side is a remote MCP connector, so it’s there from any device.
Ideas
Maybe, someday- A DIY LoRa pager for alerts: ESP32, LoRa radio, screen and buzzer in a printed case.
- An Intel Arc A310 if Jellyfin ever needs hardware transcoding (it also does HEVC and AV1 encoding).
- A remote power button: an ESP32 and a relay across the front-panel header.
- 4K UHD ripping, depending on the drive (see above).