Proxmox VEXXIII · Home LabSelf-hosting patterns
Self-hosting popular apps: Nextcloud, Jellyfin, Pi-hole, Vaultwarden
What you'll learn
- Choose between VM and LXC for common self-hosted apps
- Set up a reverse proxy with automatic TLS for public-facing services
- Tune each app for low-resource home-lab hardware
- Plan backups for self-hosted data
Prerequisites
Verified against Proxmox VE 9.2.4 · Proxmox Backup Server 4.2.5 · Ceph Squid / Tentacle · Debian 13 (Trixie) · Linux kernel 7.0 (PVE 9.2 default) · 2026-08-07
The self-hosting stack
A typical home-lab “essentials” stack:
- Reverse proxy + TLS — Caddy or Nginx Proxy Manager
- DNS-based ad blocker — Pi-hole or AdGuard Home
- Password manager — Vaultwarden (Bitwarden-compatible)
- File sync & share — Nextcloud
- Media server — Jellyfin or Plex
- Smart home hub — Home Assistant (later lesson)
- Backups — Proxmox Backup Server (already covered)
This lesson covers the first five. Each gets the same treatment: install, configure for low resources, integrate with the reverse proxy, back up.
Reverse proxy: Caddy
A reverse proxy sits in front of your apps, terminates TLS, and routes requests based on hostname.
# Create an LXC for Caddy (Debian 12 template)
pct create 200 local:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst --hostname caddy --memory 512 --cores 1 --net0 name=eth0,bridge=vmbr0,ip=192.168.1.30/24,gw=192.168.1.1 --rootfs local-lvm:8
pct start 200
pct enter 200
# Inside the LXC
apt update && apt install -y caddy
# Configure /etc/caddy/Caddyfile
# (heredoc replaced)
# Create the Caddyfile with the configuration below
# Write each line using printf to avoid shell escaping issues
printf '%s
' '# Ad-blocking on the LAN — point your router DHCP DNS to this' '# Pi-hole is handled separately (see below)' '' '# Public-facing services' 'nextcloud.lab.example.com reverse_proxy 192.168.1.31:80' 'jellyfin.lab.example.com reverse_proxy 192.168.1.32:8096' 'vault.lab.example.com reverse_proxy 192.168.1.33:80' > /etc/caddy/Caddyfile
# (This is a simplified version; for full Caddyfile syntax with blocks,
# use a heredoc approach or template file)
systemctl reload caddy
Pi-hole
# Create an LXC for Pi-hole
pct create 201 local:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst \
--hostname pihole --memory 256 --cores 1 \
--net0 name=eth0,bridge=vmbr0,ip=192.168.1.34/24,gw=192.168.1.1 \
--rootfs local-lvm:4
pct start 201
pct enter 201
# Install Pi-hole
curl -sSL https://install.pi-hole.net | bash
# Follow the prompts; choose all defaults except:
# - Upstream DNS: Cloudflare (1.1.1.1) or Quad9
# - Web admin: yes
# - Logging: optional (disable for less disk I/O)
# Set the admin password
pihole -a -p
# Configure your router's DHCP to use 192.168.1.34 as the primary DNS
# This makes every device on your network use Pi-hole for DNS
Vaultwarden
# Create a small VM or LXC — Vaultwarden is a Rust binary, very lightweight
pct create 202 local:vztmpl/debian-12-standard_12.2-1_amd64.tar.zst --hostname vault --memory 512 --cores 1 --net0 name=eth0,bridge=vmbr0,ip=192.168.1.33/24,gw=192.168.1.1 --rootfs local-lvm:4
pct start 202
pct enter 202
# Install via the official installer (Docker) or as a standalone binary
apt install -y docker.io docker-compose
mkdir -p /opt/vaultwarden
cd /opt/vaultwarden
# (heredoc replaced)
echo "services:" >> docker-compose.yml
echo " vaultwarden:" >> docker-compose.yml
echo " image: vaultwarden/server:latest" >> docker-compose.yml
echo " restart: unless-stopped" >> docker-compose.yml
echo " volumes:" >> docker-compose.yml
echo " - ./data:/data" >> docker-compose.yml
echo " ports:" >> docker-compose.yml
echo " - "80:80"" >> docker-compose.yml
docker compose up -d
For production-quality setup, put Vaultwarden behind Caddy with HTTPS, enable the admin token, set up SMTP for invite emails.
Nextcloud
Nextcloud is more resource-hungry than the others. Give it a real VM (not LXC) for stability.
# Create a VM (Ubuntu 24.04 LTS recommended for Nextcloud)
qm create 110 --name nextcloud --memory 4096 --cores 2 \
--net0 virtio,bridge=vmbr0 \
--scsihw virtio-scsi-single --scsi0 local-lvm:32,iothread=1 \
--ide2 local:iso/ubuntu-24.04-live-server-amd64.iso,media=cdrom \
--boot order=scsi0 --ostype l26
# ... install Ubuntu via the standard installer, set hostname, static IP
# Inside the VM, install Nextcloud via the snap (easiest) or manually
sudo snap install nextcloud
# Or manual install: see https://docs.nextcloud.com/server/latest/admin_manual/installation/
Performance tuning
Nextcloud on a home lab benefits from:
- Redis for file locking cache (reduces DB load)
- APCu for local PHP opcode cache
- PHP-FPM with tuned
pm.max_children - Cron jobs (not AJAX) for background tasks
- Preview generation disabled or limited (very I/O-heavy)
Jellyfin
Jellyfin is a free media server that organises movies, TV, music, and photos.
# Hardware acceleration is the difference between "works" and "struggles"
# Check your CPU for Intel QuickSync or AMD VCE
# If using a mini-PC with Intel CPU:
qm create 120 --name jellyfin --memory 4096 --cores 2 \
--net0 virtio,bridge=vmbr0 \
--scsihw virtio-scsi-single --scsi0 local-lvm:32 \
--hostpci0 0000:00:02.0,pcie=1,x-vga=1 \
--machine pc-q35-9.0 \
--bios ovmf --efidisk0 local-lvm:1,efitype=4m \
--boot order=scsi0 --ostype l26
# Install Debian or Ubuntu, then:
sudo apt install -y jellyfin
# Or use Docker:
# docker run -d --name jellyfin -p 8096:8096 jellyfin/jellyfin
Integration checklist
For each service, make sure:
- Service has its own LXC/VM with appropriate resources
- Service is on a static IP
- Backup is configured (PBS for the LXC/VM, plus service-level backup for app data)
- Reverse proxy rule is in place (for HTTPS)
- DNS record points to your reverse proxy
- Service admin password is in your Vaultwarden
- Smoke test from a separate device works
Resource planning
Typical home-lab resource use:
| Service | RAM | Disk | Type |
|---|---|---|---|
| Caddy | 128 MB | 2 GB | LXC |
| Pi-hole | 128 MB | 2 GB | LXC |
| Vaultwarden | 256 MB | 2 GB | LXC |
| Nextcloud | 2-4 GB | 50+ GB | VM |
| Jellyfin | 1-2 GB | 10+ GB + media | VM |
On a 32 GB mini-PC, this leaves ~20 GB free for the host, working memory, and a few more services.
Backup strategy
- PBS backs up the LXCs and VMs automatically — single job, daily, keep 7
- Application-level backup: Nextcloud has its own backup command; Vaultwarden data dir is just SQLite. Both are small.
- Media (Jellyfin library) doesn’t need backup if you can re-rip. Back up the metadata DB so your library doesn’t need to be rescanned.
# PBS job via UI: Datacenter → Backup → Add
# Schedule: daily 02:00
# Selection: All
# Retention: keep daily=7, weekly=4, monthly=3
Key takeaways
- Caddy gives you free TLS for public-facing services
- Pi-hole, Vaultwarden, and Caddy all fit comfortably in small LXCs
- Nextcloud and Jellyfin need real VMs and care about resources
- Hardware passthrough for Jellyfin transcoding is worth the effort if your mini-PC has an Intel GPU
- Always back up — even a single-node home lab benefits from PBS
Knowledge check
Knowledge check · 4 questions
Q1. Which of these self-hosted apps fits comfortably in a 256 MB LXC?
Q2. Which reverse proxy automatically obtains and renews Let’s Encrypt certificates?
Q3. Name one resource-heavy self-hosted app that benefits from running in a VM rather than an LXC.
Q4. Reconstruct the answer from the lesson context.
Passing score: 75%. Answers are checked in this browser.