Modern Smart TVs, particularly budget models like the Xiaomi Mi TV running on the hermano or Hartens platforms, often come equipped with chipsets that prioritize basic functionality over performance. These devices typically struggle with even the simplest tasks, such as rendering launcher menus, due to their limited processing power and memory—often only 1 to 1.5 GB of RAM, with a significant portion consumed by the operating system and graphical stack.
When attempting to run TorrServer directly on such a TV, users may encounter several issues:
- Network Storm: The server engages in extensive communication with the torrent network, generating hundreds of connections per second. This overloads the Android network stack and the TV’s weak Wi-Fi chip, resulting in dropped streams and even complete network failure.
- RAM Shortage: Parsing torrent files and buffering heavy 4K video can consume hundreds of megabytes of RAM. The Android system detects a critical RAM shortage, aggressively terminating background services—including the media player—or crashing due to Out of Memory (OOM) errors.
- CPU Throttling: The CPU is pushed to its limits by hashing and assembling torrent packets on-the-fly, causing the TV to overheat, throttle its core frequencies, and ultimately deliver a slideshow experience instead of smooth playback.
The solution is straightforward: move TorrServer off the TV. Allow the TV to function as a standard media player that renders a ready-made HTTP video stream, while delegating the heavy lifting of downloading, hashing, and buffering to a dedicated home server.
Deploying an LXC Container on Proxmox
To set up TorrServer, I opted for a lightweight Debian 12 LXC container on my Proxmox VE host, identified as damba (192.168.188.66). Initially, I planned to use VMID 211, but it was already occupied by a Vaultwarden instance, so I selected 212 instead. A full virtual machine isn’t necessary for TorrServer; a lightweight unprivileged LXC container suffices. I allocated modest resources:
- VMID:
212 - Hostname:
torrserver - CPU: 2 cores—sufficient for rapid metadata parsing of large torrents.
- RAM: 2 GB (for the OS and caching).
- Swap: 512 MB.
- Disk: 8 GB on the
local-lvmpool (LVM-thin). - Network: static IP
192.168.188.65/24, gateway192.168.188.1. I set the DNS server to my local AdGuard Home (192.168.188.53).
Creating the container can be accomplished with a single command on the Proxmox host:
pct create 212 local:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst
-cores 2 -memory 2048 -swap 512
-net0 name=eth0,bridge=vmbr0,ip=192.168.188.65/24,gw=192.168.188.1
-nameserver 192.168.188.53 -ostype debian -storage local-lvm -rootfs 8
-unprivileged 1 -features nesting=1 -onboot 1
After creating the container, I started it and accessed its console:
pct start 212
pct enter 212
I then installed the stable release of TorrServer MatriX.141.4 and created a systemd service for automatic startup:
# Download the binary
wget -O /usr/bin/TorrServer https://github.com/YouROK/TorrServer/releases/download/MatriX.141/TorrServer-linux-amd64
chmod +x /usr/bin/TorrServer
# Create the systemd service configuration
cat < /etc/systemd/system/torrserver.service
[Unit]
Description=TorrServer Media Server
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/TorrServer -d /opt/torrserver -p 8090
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# Reload systemd and enable the service
systemctl daemon-reload
systemctl enable --now torrserver
To verify that the service is listening on port 8090, I used the following commands:
systemctl status torrserver
ss -tlnp | grep 8090
Preserving Host SSD: Configuring RAM Cache
If TorrServer is left with default settings, it may write cache data to disk. For a home server running Proxmox on a standard consumer SSD, this can be detrimental. Streaming a single 4K film can generate up to 80–100 GB of data rewrites, potentially exhausting the TBW (terabytes written) limit of an inexpensive drive within months of active use.
The solution is to cache data exclusively in RAM. However, there is a caveat: in the Matrix versions of TorrServer, the standard GET request to /settings returns a 404 error. Settings are now retrieved and configured via POST requests to the API. To configure the RAM cache, I sent a JSON packet to port 8090:
curl -s -X POST -H "Content-Type: application/json"
-d '{"action": "set", "sets": {"UseDisk": false, "CacheSize": 536870912, "PreloadCache": 30, "ConnectionsLimit": 200}}'
http://192.168.188.65:8090/settings
Key parameters include:
"UseDisk": false—disables disk caching, ensuring the buffer is only written to RAM, thus preserving the SSD’s lifespan."CacheSize": 536870912—allocates exactly 512 MB for the buffer (size is specified in bytes), an optimal amount for smoothing out internet speed fluctuations during heavy downloads."PreloadCache": 30—sets a preload buffer of 30% of the cache size, ensuring playback begins only after approximately 150 MB of data is buffered in memory, preventing interruptions during viewing."ConnectionsLimit": 200—limits connections to avoid overwhelming budget routers, which can struggle with 500+ connections. This limit strikes a balance, providing high download speeds without network lag.
To verify that the settings were applied, I executed the following request:
curl -s -X POST -H "Content-Type: application/json" -d '{"action": "get"}' http://192.168.188.65:8090/settings
Ensuring Resilience: Watchdog Script on PVE Host
With the container running and settings applied, the movies play smoothly. However, what if the TorrServer service hangs due to a problematic torrent or network overload? Or if the LXC container itself becomes unresponsive? Manually accessing via SSH to restart it is tedious. An automated monitoring solution is necessary.
I developed a watchdog bash script /root/torrserver-watchdog.sh that runs directly on the Proxmox VE host. It checks for three failure scenarios:
- If LXC container 212 is not running, it starts the container.
- If the cgroups subsystem within the PVE kernel hangs, causing the container to appear running while commands like
pct exechang indefinitely, it forcibly stops the container usingpct stopand restarts it. - If the container is alive but TorrServer is unresponsive to HTTP requests (port 8090), it restarts the
systemdservice within the LXC, and if that fails, it restarts the entire container.
Here’s the script code:
#!/usr/bin/env bash
# /root/torrserver-watchdog.sh — TorrServer watchdog script.
# Log file: /var/log/torrserver-watchdog.log
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
LXC_ID=212
TORRSERVER_IP="192.168.188.65"
LOG_FILE="/var/log/torrserver-watchdog.log"
# Rotate log if it exceeds 100 KB
if [ -f "$LOG_FILE" ] && [ "$(wc -c > "$LOG_FILE"
}
# 1) Check if the container is running
STATUS=$(pct status $LXC_ID 2>&1)
if [[ "$STATUS" != *"status: running"* ]]; then
log_msg "TorrServer LXC $LXC_ID is not running. Starting container..."
pct start $LXC_ID 2>&1 >> "$LOG_FILE"
exit 0
fi
# 2) Check for hung cgroups (pct exec hangs)
timeout 5 pct exec $LXC_ID -- systemctl is-active torrserver >/dev/null 2>&1
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ]; then
if [ $EXIT_CODE -eq 124 ]; then
log_msg "LXC $LXC_ID hung in userland cgroups (pct exec timeout). Restarting container..."
pct stop $LXC_ID 2>&1 >> "$LOG_FILE"
sleep 2
pct start $LXC_ID 2>&1 >> "$LOG_FILE"
exit 0
else
log_msg "TorrServer is not active (code $EXIT_CODE). Restarting service..."
pct exec $LXC_ID -- systemctl restart torrserver 2>&1 >> "$LOG_FILE"
exit 0
fi
fi
# 3) Check HTTP API responsiveness
HTTP_CODE=$(curl --max-time 5 -s -o /dev/null -w "%{http_code}" "http://${TORRSERVER_IP}:8090/")
if [ "$HTTP_CODE" -ne 200 ] && [ "$HTTP_CODE" -ne 404 ]; then
log_msg "TorrServer is unresponsive to HTTP (code '$HTTP_CODE'). Restarting service..."
pct exec $LXC_ID -- systemctl restart torrserver 2>&1 >> "$LOG_FILE"
sleep 5
# Final check
HTTP_CODE_AGAIN=$(curl --max-time 5 -s -o /dev/null -w "%{http_code}" "http://${TORRSERVER_IP}:8090/")
if [ "$HTTP_CODE_AGAIN" -ne 200 ] && [ "$HTTP_CODE_AGAIN" -ne 404 ]; then
log_msg "Persistent HTTP failure. Restarting container..."
pct stop $LXC_ID 2>&1 >> "$LOG_FILE"
sleep 2
pct start $LXC_ID 2>&1 >> "$LOG_FILE"
else
log_msg "HTTP service is responsive again."
fi
fi
After saving the script, I made it executable and scheduled it in the Proxmox cron to run every two minutes:
chmod +x /root/torrserver-watchdog.sh
crontab -e
# Add the following line:
# */2 * * * * /root/torrserver-watchdog.sh
Monitoring with Uptime Kuma
To visually track the availability of TorrServer and receive instant notifications via Telegram upon downtime, I integrated it into my existing Uptime Kuma instance (LXC 200). I updated the automatic configuration script for Kuma:
# uptime-kuma-setup.py
# ...
# Add TorrServer monitor
api.add_monitor(
type="http",
name="TorrServer Web",
url="http://192.168.188.65:8090/",
interval=60,
retryInterval=30,
resendInterval=0,
maxRetries=2,
notificationIDList=[1] # Notification ID for Telegram alerts
)
Now, if TorrServer goes offline, I will receive a notification in my messenger before anyone in the household reaches for the TV remote.
Configuring Lampa on Android TV
The final step is to connect our server to the TVs in the rooms (specifically tv-bana and tv-room1).
- Install the Lampa application (official client) on the TV.
- Navigate to Settings > TorrServer.
- Set Connection Type to Main (or server).
- In the TorrServer Address field, enter the path to our LXC container:
http://192.168.188.65:8090. - Click the Check button. The status indicator should light up green with the server version (MatriX.141.4).
Configuring Torrent Search:
Lampa serves primarily as a visually appealing catalog and user-friendly interface. To enable torrent discovery, a parser is required.
- Go to Settings > Parser.
- Enable the Use Parser option—set to Yes.
- In the Parser Address field, enter the mirror of the Jackett wrapper:
jac.red(or your instance if deployed locally). - Enable search across all categories and ensure that the Torrents tab appears in movie cards.
To test functionality, open any large film, navigate to the “Torrents” tab, and select a torrent with a size of 50–70 GB. The video should start playing within 3–5 seconds, with instant rewind functionality. TorrServer buffers the stream in the server’s RAM, allowing the TV to play the prepared video stream without any lag or overheating.
Summary of Accomplishments
Transferring TorrServer from the TV to a dedicated Proxmox server has proven to be highly beneficial:
- Stability: No more freezes or crashes with Lampa.
- Quality: Smooth playback of 4K HDR releases with high bitrate without interruptions.
- Hardware Safety: Zero load on the TV’s CPU/RAM and no wear on the host’s SSD drives.
- Fault Tolerance: Any service or container hangs are automatically resolved by the watchdog script within minutes.