Follow Up 8: Build a Homelab That Does Real Work
Build a Homelab That Does Real Work
What You Learn from Building a Real-World Homelab
Building a homelab that performs real work transforms it from a hobby into a complete infrastructure learning platform. By designing, deploying, securing, monitoring, and maintaining these services, you gain hands-on experience across the entire lifecycle of modern IT systems.
1. Systems Architecture & Design Thinking
You learn how to design systems intentionally instead of piling services onto a single server.
-
How to separate workloads by function, risk, and performance
-
How to design for fault isolation, not just uptime
-
When to use VMs versus containers
-
How infrastructure decisions impact scalability and maintenance
This builds architectural judgment — knowing why something should be built a certain way, not just how.
2. Network Engineering & Segmentation
Running multiple services forces you to think like a network engineer.
-
VLAN design and traffic isolation (Management, Trusted, IoT, Media)
-
Firewall policy creation using deny-by-default principles
-
Secure WAN exposure using VPNs and reverse proxies
-
How lateral movement happens — and how to stop it
You gain real experience implementing zero-trust concepts in a practical environment.
3. Security as a First-Class Requirement
Security stops being an afterthought and becomes part of every deployment.
-
TLS automation and certificate management
-
Secure authentication and MFA enforcement
-
Secrets management and encryption at rest
-
Reducing attack surface by limiting public exposure
-
Designing backup strategies that assume compromise or failure
You learn to treat security controls as infrastructure, not add-ons.
4. Virtualization & Containerization Mastery
Operating Proxmox and Docker together teaches platform-level thinking.
-
Resource pooling and workload isolation
-
Snapshotting, backups, and recovery at the hypervisor level
-
Container lifecycle management and persistence
-
Performance tuning and resource contention awareness
This experience mirrors real enterprise environments where virtualization and containers coexist.
5. Automation & Infrastructure as Code
Manual configuration quickly becomes unsustainable — automation becomes necessary.
-
Rebuilding systems from Ansible playbooks
-
Standardizing deployments across hosts
-
Eliminating configuration drift
-
Recovering faster from failures through repeatability
You learn that reliability comes from automation, not hero troubleshooting.
6. Observability & Operational Awareness
Monitoring changes how you think about systems.
-
Metrics vs logs vs alerts
-
Building dashboards that reflect service health
-
Detecting failures before users report them
-
Using data to drive capacity planning and scaling decisions
This builds intuition for what “normal” looks like — a critical operational skill.
7. Backup, Disaster Recovery & Resilience
Failure becomes expected instead of feared.
-
Designing backups that are portable and restorable
-
Testing recovery instead of assuming backups work
-
Recovering from host loss, data corruption, and service failure
-
Understanding Recovery Time Objectives (RTO) and Recovery Point Objectives (RPO)
You learn how to restore services under pressure, not just build them.
8. Change Management & Operational Discipline
You gain experience managing systems long-term.
-
Patch cadence and maintenance windows
-
Snapshot-first change workflows
-
Risk evaluation before deploying changes
-
Documentation as part of operations
This develops the mindset required to run production systems without constant outages.
9. Capacity Planning & Growth Modeling
The lab grows — and you learn how to manage that growth responsibly.
-
Identifying early signs of resource exhaustion
-
Scaling horizontally vs vertically
-
Planning hardware upgrades before outages occur
-
Matching infrastructure investment to actual demand
You learn to justify scaling decisions using data, not guesswork.
10. Platform Evolution & Kubernetes Readiness
Instead of jumping blindly into Kubernetes, you learn when it makes sense.
-
Mapping Docker workloads to Kubernetes primitives
-
Understanding operational overhead vs benefit
-
Migrating services incrementally
-
Recognizing when Kubernetes is unnecessary
This builds strategic thinking — choosing the right tool for the problem.
The Big Picture Lesson
The most important thing you learn is that infrastructure is not about tools — it’s about responsibility.
This lab teaches you how to:
-
Design systems that survive failure
-
Secure services without sacrificing usability
-
Automate for reliability and speed
-
Operate systems calmly under change and pressure
A lab that does real work turns you from someone who knows technologies into someone who can run systems.
___________________________________________________________________________________
This guide provides step-by-step instructions for deploying practical homelab services across multiple environments. Each section covers:
Bare metal / VM
Docker / Docker Compose
(Where applicable) Appliance-style installs
The goal is not just to install software, but to build maintainable, secure, real-world services you’ll continuously improve.
1. Home Automation – Home Assistant
Environment A: Dedicated Appliance (Home Assistant OS)
Best for: Simplicity, stability, low maintenance
Steps
Download the Home Assistant OS image for your hardware.
Flash the image to SSD/SD using Balena Etcher.
Boot the device and wait ~10 minutes.
Browse to
http://homeassistant.local:8123.Create an admin account.
Restore from backup (optional).
Add integrations (Zigbee, Z-Wave, MQTT, etc.).
What you learn
Appliance-style OS management
Add-ons vs integrations
Backup/restore workflows
Environment B: Docker / Docker Compose
Best for: Advanced users, shared servers
Steps
Install Docker and Docker Compose.
Create a directory
homeassistant/.Create
docker-compose.yml:version: '3' services: homeassistant: image: homeassistant/home-assistant:stable container_name: homeassistant network_mode: host volumes: - ./config:/config restart: unless-stoppedRun
docker compose up -d.Access via
http://host-ip:8123.Configure integrations and dashboards.
What you learn
Host networking
Persistent volumes
Container lifecycle management
2. Media Server – Plex / Jellyfin
Environment A: VM or Bare Metal
Steps
Install Ubuntu Server.
Mount media storage (
/media/movies,/media/tv).Install Plex or Jellyfin via repository/package.
Enable and start the service.
Access the web UI.
Add libraries and scan content.
Enable hardware transcoding (if supported).
What you learn
Filesystem permissions
Media codecs and transcoding
GPU passthrough basics
Environment B: Docker Compose
Steps
Create directories for config and media.
Create
docker-compose.yml:services: jellyfin: image: jellyfin/jellyfin ports: - "8096:8096" volumes: - ./config:/config - /media:/media restart: unless-stoppedStart the container.
Configure libraries in UI.
What you learn
Bind mounts
Containerized media stacks
Reverse proxy integration
3. Personal Cloud – Nextcloud
Environment A: VM (LAMP Stack)
Steps
Install Ubuntu Server.
Install Apache, PHP, MariaDB.
Create a database and user.
Download and extract Nextcloud.
Configure Apache virtual host.
Secure with TLS.
Run web installer.
What you learn
Web stack administration
Database backups
PHP tuning
Environment B: Docker Compose
Steps
Create directories for data and config.
Use official Nextcloud Compose example.
Deploy Nextcloud + database.
Complete setup wizard.
Enable apps (Calendar, Contacts).
What you learn
Multi-container apps
Persistent storage
Service dependencies
4. VPN Access – WireGuard
Environment A: Linux Server
Steps
Install WireGuard.
Generate server and client keys.
Configure
wg0.conf.Enable IP forwarding.
Start WireGuard service.
Configure firewall/NAT.
Import client config.
What you learn
Tunneling
Routing
Key-based authentication
Environment B: Docker (wg-easy)
Steps
Deploy wg-easy container.
Access web UI.
Generate clients.
Download configs.
Test remote access.
What you learn
Simplified VPN management
Secure service exposure
5. Self-Hosted Password Vault – Bitwarden / Vaultwarden
Environment A: Docker (Recommended)
Steps
Install Docker.
Deploy Vaultwarden container.
Configure environment variables.
Reverse proxy with HTTPS.
Create admin account.
Enable 2FA.
What you learn
Secrets management
Encryption at rest
Zero-trust principles
6. Network Monitoring – Prometheus + Grafana
Environment A: VM
Steps
Install Prometheus.
Install node_exporter.
Configure scrape targets.
Install Grafana.
Add Prometheus as data source.
Import dashboards.
What you learn
Metrics vs logs
Time-series databases
Alerting
Environment B: Docker Compose
Steps
Deploy Prometheus and Grafana containers.
Mount config files.
Expose Grafana UI.
Import dashboards.
Configure alerts.
What you learn
Observability stacks
Container monitoring
Final Integration Projects
VPN + Nextcloud for remote work
Home Assistant + Grafana dashboards
Bitwarden + VPN for secure access
A lab that solves real problems becomes a platform for continuous learning, hardening, and automation.
Appendix A – Command-by-Command Installs (Copy/Paste Ready)
Common Base (Ubuntu Server 22.04+)
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget git ufw ca-certificates gnupg lsb-release
Docker + Docker Compose
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
newgrp docker
sudo apt install -y docker-compose-plugin
Home Assistant (Docker)
mkdir -p ~/homeassistant/config
cd ~/homeassistant
cat <<EOF > docker-compose.yml
version: '3'
services:
homeassistant:
image: homeassistant/home-assistant:stable
network_mode: host
volumes:
- ./config:/config
restart: unless-stopped
EOF
docker compose up -d
Jellyfin Media Server (Docker)
mkdir -p ~/jellyfin/{config,cache}
cat <<EOF > docker-compose.yml
services:
jellyfin:
image: jellyfin/jellyfin
ports:
- "8096:8096"
volumes:
- ./config:/config
- ./cache:/cache
- /media:/media
restart: unless-stopped
EOF
docker compose up -d
Nextcloud (Docker)
mkdir -p ~/nextcloud
cd ~/nextcloud
cat <<EOF > docker-compose.yml
version: '3'
services:
db:
image: mariadb
command: --transaction-isolation=READ-COMMITTED
environment:
MYSQL_ROOT_PASSWORD=strongrootpass
MYSQL_DATABASE=nextcloud
MYSQL_USER=nextcloud
MYSQL_PASSWORD=strongpass
volumes:
- db:/var/lib/mysql
app:
image: nextcloud
ports:
- 8080:80
volumes:
- nextcloud:/var/www/html
depends_on:
- db
volumes:
db:
nextcloud:
EOF
docker compose up -d
WireGuard (wg-easy)
docker run -d \
--name=wg-easy \
-e WG_HOST=your.domain.com \
-e PASSWORD=adminpassword \
-v ~/.wg-easy:/etc/wireguard \
-p 51820:51820/udp \
-p 51821:51821/tcp \
--cap-add=NET_ADMIN \
--cap-add=SYS_MODULE \
--sysctl="net.ipv4.conf.all.src_valid_mark=1" \
weejewel/wg-easy
Vaultwarden (Bitwarden)
mkdir -p ~/vaultwarden
cat <<EOF > docker-compose.yml
services:
vaultwarden:
image: vaultwarden/server
ports:
- "8081:80"
volumes:
- ./data:/data
environment:
WEBSOCKET_ENABLED: 'true'
restart: unless-stopped
EOF
docker compose up -d
Prometheus + Grafana
mkdir -p ~/monitoring
cd ~/monitoring
cat <<EOF > docker-compose.yml
version: '3'
services:
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- 9090:9090
grafana:
image: grafana/grafana
ports:
- 3000:3000
restart: unless-stopped
EOF
Appendix B – Network Architecture & VLAN Design
[ Internet ]
|
[ Firewall / Router ]
|
---------------------------
| VLAN 10 – Management |
| - VPN Server |
| - Grafana |
---------------------------
| VLAN 20 – Trusted |
| - Nextcloud |
| - Vaultwarden |
---------------------------
| VLAN 30 – IoT |
| - Home Assistant |
| - Smart Devices |
---------------------------
| VLAN 40 – Media |
| - Plex/Jellyfin |
---------------------------
Reverse Proxy Placement
Runs in Trusted VLAN
Only service exposed to WAN (443)
Routes traffic internally via DNS or IP
Appendix C – Security Hardening (Per Service)
Home Assistant
Disable cloud unless required
Isolate IoT VLAN
Use long-lived tokens sparingly
Media Servers
Internal-only access
VPN for remote streaming
Regular updates
Nextcloud
HTTPS only
Enable 2FA
Daily DB + file backups
VPN
Key-based auth only
Firewall restrict admin UI
Vaultwarden
HTTPS mandatory
Admin panel disabled after setup
Encrypted offsite backups
Monitoring
No public exposure
Read-only dashboards for users
Appendix D – Hardware Sizing Recommendations
| Service | CPU | RAM | Storage |
|---|---|---|---|
| Home Assistant | 2 cores | 2–4 GB | 32 GB |
| Jellyfin | 4 cores | 4–8 GB | Media dependent |
| Nextcloud | 4 cores | 8 GB | SSD + Data |
| VPN | 1–2 cores | 1 GB | Minimal |
| Vaultwarden | 1 core | 1 GB | <10 GB |
| Monitoring | 2 cores | 4 GB | 50 GB |
Suggested Host
Mini PC / NUC (8–16 cores, 32 GB RAM)
SSD for OS, HDD/NAS for media
Appendix E – Reverse Proxy with Full TLS Automation
Option A: Caddy (Recommended – simplest)
Why Caddy
Automatic HTTPS (Let's Encrypt)
Minimal configuration
Great for homelabs
Install Caddy (Docker)
mkdir -p ~/caddy
cd ~/caddy
cat <<EOF > docker-compose.yml
version: '3'
services:
caddy:
image: caddy:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
restart: unless-stopped
volumes:
caddy_data:
caddy_config:
EOF
Example Caddyfile
nextcloud.yourdomain.com {
reverse_proxy nextcloud:80
}
vault.yourdomain.com {
reverse_proxy vaultwarden:80
}
grafana.yourdomain.com {
reverse_proxy grafana:3000
}
Start:
docker compose up -d
Option B: NGINX + Certbot
Install NGINX
sudo apt install -y nginx
Install Certbot
sudo apt install -y certbot python3-certbot-nginx
Example NGINX Site
server {
server_name nextcloud.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
Enable TLS
sudo certbot --nginx -d nextcloud.yourdomain.com
Appendix F – Proxmox-Specific Builds
Recommended VM Layout
| VM | Purpose | vCPU | RAM | Storage |
|---|---|---|---|---|
| pve-mgmt | VPN + Proxy | 2 | 2 GB | 32 GB |
| pve-apps | Nextcloud + Vaultwarden | 4 | 8 GB | 100 GB |
| pve-media | Jellyfin | 4–8 | 8–16 GB | Media disk |
| pve-monitor | Grafana/Prometheus | 2 | 4 GB | 50 GB |
| pve-ha | Home Assistant OS | 2 | 4 GB | 32 GB |
Resource Pools
Critical: VPN, Vaultwarden
Services: Nextcloud, Home Assistant
Media: Jellyfin
Monitoring: Grafana
Apply memory ballooning only to Media/Monitoring pools.
Storage Strategy
Local SSD (ZFS): OS + containers
HDD/NAS passthrough: Media
Weekly ZFS snapshots
Appendix G – Backup Automation Scripts
Docker Volume Backups
mkdir -p ~/backups/docker
cat <<'EOF' > backup_docker_volumes.sh
#!/bin/bash
DATE=$(date +%F)
DEST=~/backups/docker/$DATE
mkdir -p $DEST
docker volume ls -q | while read vol; do
docker run --rm -v $vol:/volume -v $DEST:/backup alpine \
tar czf /backup/${vol}.tar.gz /volume
done
EOF
chmod +x backup_docker_volumes.sh
Nextcloud Database Backup
cat <<'EOF' > backup_nextcloud_db.sh
#!/bin/bash
DATE=$(date +%F)
docker exec nextcloud-db mysqldump -u nextcloud -pnextcloud nextcloud \
> ~/backups/nextcloud-db-$DATE.sql
EOF
chmod +x backup_nextcloud_db.sh
Offsite Sync (rsync)
rsync -av --delete ~/backups user@backuphost:/srv/homelab-backups
Final Recommendation
Build VPN + Reverse Proxy first
Deploy Vaultwarden immediately
Add Nextcloud and backups
Layer in Monitoring
Finish with Home Automation & Media
This structure mirrors real enterprise environments and gives you a lab that continuously earns its keep.
Appendix H – Firewall Rulesets (pfSense / OPNsense)
VLAN Definitions (Example)
VLAN 10 – Management (10.10.10.0/24)
VLAN 20 – Trusted Services (10.10.20.0/24)
VLAN 30 – IoT (10.10.30.0/24)
VLAN 40 – Media (10.10.40.0/24)
VLAN 99 – WAN
Global Rules (Floating)
| Action | Source | Destination | Ports | Description |
|---|---|---|---|---|
| Allow | Management | Any VLAN | Any | Admin access |
| Block | IoT | Management | Any | Prevent lateral movement |
| Block | Media | Management | Any | Protect admin plane |
IoT VLAN Rules
| Action | Source | Destination | Ports | Notes |
|---|---|---|---|---|
| Allow | IoT Net | Home Assistant | 8123 | Automation control |
| Allow | IoT Net | DNS | 53 | Name resolution |
| Allow | IoT Net | Internet | 443 | Cloud APIs |
| Block | IoT Net | RFC1918 | Any | Block LAN access |
Trusted Services VLAN Rules
| Action | Source | Destination | Ports | Notes |
|---|---|---|---|---|
| Allow | VPN Net | Trusted Net | Any | Remote access |
| Allow | Trusted Net | Internet | 443 | Updates |
| Block | Trusted Net | IoT Net | Any | Isolation |
WAN Rules
| Action | Source | Destination | Ports | Notes |
|---|---|---|---|---|
| Allow | Any | Reverse Proxy | 443 | HTTPS only |
| Allow | Any | VPN Server | 51820/UDP | WireGuard |
| Block | Any | Any | Any | Default deny |
Appendix I – Grafana Dashboard Imports
Recommended Dashboards
| Purpose | Dashboard ID |
|---|---|
| Node Exporter Full | 1860 |
| Docker Monitoring | 179 |
| SNMP Network Devices | 11169 |
| VPN Monitoring | 13764 |
Import Steps
Log into Grafana
Dashboards → Import
Enter Dashboard ID
Select Prometheus data source
Save
Appendix J – Disaster Recovery Walkthroughs
Scenario 1: Full VM Loss (Proxmox)
Steps
Reinstall Proxmox
Recreate storage pools
Restore VM from backup
Validate network bridges
Start services
Scenario 2: Docker Host Failure
sudo apt install docker docker-compose-plugin
rsync -av backups/ ~/backups
docker compose up -d
Verify services via reverse proxy.
Scenario 3: Nextcloud Data Corruption
docker compose down
tar xzf nextcloud-volume.tar.gz
docker compose up -d
Restore DB dump if needed.
Appendix K – Ansible Playbooks (Infrastructure Rebuild)
Inventory
[homelab]
proxy ansible_host=10.10.10.10
apps ansible_host=10.10.20.10
monitor ansible_host=10.10.10.20
Base Role (roles/base/tasks/main.yml)
- name: Update system
apt:
update_cache: yes
upgrade: dist
- name: Install base packages
apt:
name:
- curl
- git
- ufw
state: present
Docker Role (roles/docker/tasks/main.yml)
- name: Install Docker
shell: curl -fsSL https://get.docker.com | sh
- name: Add user to docker group
user:
name: '{{ ansible_user }}'
groups: docker
append: yes
Deploy Stack Playbook
- hosts: homelab
roles:
- base
- docker
Final Notes
With firewall policy, observability, disaster recovery, and configuration management added, this homelab mirrors real enterprise infrastructure lifecycle management.
Appendix L – Capacity Planning & Growth Modeling
Baseline Metrics to Track
CPU utilization (avg / p95)
Memory usage and swap activity
Disk IOPS and latency
Network throughput and packet loss
Container restart counts
Collect via Prometheus + Grafana and review weekly.
Growth Modeling Framework
Phase 1 – Initial (1–10 users)
Single Proxmox host
32 GB RAM
8–12 CPU cores
1–2 TB usable storage
Phase 2 – Expansion (10–50 users)
Add second Proxmox node
Shared storage or replication
Increase RAM to 64 GB per node
Offload media to NAS
Phase 3 – Maturity (50+ users / heavy use)
3-node Proxmox cluster
Ceph or ZFS replication
Dedicated monitoring node
External backup target
Capacity Red Flags
Sustained CPU >70%
Memory ballooning regularly triggered
Disk latency >20ms
Backup windows exceeding SLA
Trigger scale-out or hardware refresh when observed.
Appendix M – Change Management & Patch Cadence
Patch Cadence
| Component | Frequency |
|---|---|
| Host OS | Monthly |
| Containers | Bi-weekly |
| Firewall | Quarterly |
| Firmware | Semi-annual |
Change Workflow
Snapshot VM or container
Apply change in maintenance window
Validate service health
Monitor logs/metrics for 24h
Document change
Maintenance Windows
Low usage hours (02:00–04:00)
One service at a time
Rollback plan prepared
Appendix N – Kubernetes Migration Path
Why Migrate
Better scaling
Declarative state
Self-healing workloads
Migration Stages
Stage 1 – Prep
Standardize Docker Compose files
Externalize configs and secrets
Introduce container registries
Stage 2 – Single-Node Kubernetes
Deploy k3s or MicroK8s
Migrate non-critical services
Learn kubectl, manifests, Helm
Stage 3 – Multi-Node Cluster
Add worker nodes
Deploy MetalLB for load balancing
Replace reverse proxy with Ingress
Service Mapping
| Docker Service | Kubernetes Replacement |
|---|---|
| Docker Compose | Helm charts |
| Caddy | Ingress Controller |
| Volumes | PersistentVolumeClaims |
| Env vars | ConfigMaps / Secrets |
When NOT to Migrate
Fewer than 5 services
No need for auto-scaling
Limited operational time
Final Assessment
You now have a homelab that covers architecture, operations, security, scalability, and recovery — the full infrastructure lifecycle.
Comments
Post a Comment
Got something to say? Drop a comment below — let’s chat!