Skip to main content
RunBook Academy

Proxmox VEXXIII · Home LabSelf-hosting patterns

Self-hosting popular apps: Nextcloud, Jellyfin, Pi-hole, Vaultwarden

Intermediate⏱ ~22 min🧪 Lab requiredA registered domain or duckdns.org / no-ip.com for a free subdomain

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

Not yet marked complete on this device.

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.

Read-only / Safe
# 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

Read-only / Safe
# 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:

ServiceRAMDiskType
Caddy128 MB2 GBLXC
Pi-hole128 MB2 GBLXC
Vaultwarden256 MB2 GBLXC
Nextcloud2-4 GB50+ GBVM
Jellyfin1-2 GB10+ GB + mediaVM

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

  1. Q1. Which of these self-hosted apps fits comfortably in a 256 MB LXC?

  2. Q2. Which reverse proxy automatically obtains and renews Let’s Encrypt certificates?

  3. Q3. Name one resource-heavy self-hosted app that benefits from running in a VM rather than an LXC.

  4. Q4. Reconstruct the answer from the lesson context.

Passing score: 75%. Answers are checked in this browser.