AI Disclosure: This setup was built and partially documented with significant assistance from AI tools (Gemini, local models via Ollama).
🌐 English · Español
graph TD
%% Internet & Perimeter
Internet(("Internet")) --- ISP["ISP Router - Bridge/Passthru Mode"]
ISP --- Router["Dedicated Router - Full Control"]
subgraph Proxmox_Node ["Proxmox Server"]
PVE["Proxmox Hypervisor"]
subgraph LXC_Net ["LXC: Network Services"]
Pihole["Pi-hole + Unbound"]
TS["Tailscale - Secure Remote Access"]
end
subgraph VM_Debian ["VM: Debian Trixie"]
Docker["Docker Engine"]
Docker --- Caddy["Caddy - Reverse Proxy"]
Docker --- CS["CrowdSec - IPS/IDS"]
Docker --- Apps["All Other Apps"]
Restic["Restic - Encrypted Backups"]
end
end
%% Network connections
Router --- Switch["Switch / AP"]
Switch --- PVE
Router ---|"DNS"| Pihole
%% Remote access
Internet ---|"VPN"| TS
%% DNS flow
Apps -.->|"DNS Queries"| Pihole
%% Backup destinations
Restic -.->|"Local Backup"| WS["Workstation"]
Restic -.->|"Offsite Backup"| B2[("Backblaze B2")]
%% Styling
style Router fill:#f96,stroke:#333,stroke-width:2px
style Pihole fill:#4f4,stroke:#333
style Caddy fill:#44f,color:#fff
style CS fill:#f44,color:#fff
style Restic fill:#00b4d8,color:#fff
style B2 fill:#e21b29,color:#fff
| Service | Description | Role |
|---|---|---|
| Pi-hole | Blocks ads and trackers at the DNS level for every device on the network — phones, smart TVs, consoles — no per-device setup required | Ad blocker |
| Unbound | Recursive DNS resolver — queries root DNS servers directly without relying on third-party providers | DNS |
| Tailscale | Zero-config VPN — secure remote access to all services from anywhere | Remote access |
| Caddy | Reverse proxy with internal TLS CA — HTTPS and friendly URLs (instead of IP:port) for every service without Let's Encrypt or port 443 exposure | Reverse proxy |
| CrowdSec | Collaborative WAF/IPS — blocks known bad actors using community threat intelligence feeds | Security |
| Restic + Backblaze B2 | Encrypted, deduplicated backups following a 3-2-1 strategy — data is backed up to a local workstation and to Backblaze B2 cloud storage. Runs at system level via scheduled jobs | Backups |
| Watchtower | Keeps all containers up to date automatically with Telegram notifications on each update | Updates |
| Forgejo | GitHub alternative — self-hosted Git forge with issues, pull requests, and CI/CD | Git |
| Beszel | Lightweight Datadog/Grafana Cloud alternative — CPU, RAM, disk, and Docker container monitoring | Monitoring |
| Dozzle | Real-time Docker log viewer — Papertrail alternative for local container log tailing | Logs |
| Dockge | Web UI for managing all Docker Compose stacks from a single interface | Compose management |
| Homepage | Unified dashboard with live status widgets for all services | Dashboard |
| Service | Description | Role |
|---|---|---|
| Samba | SMB file shares accessible on LAN; combined with Tailscale, acts as a self-hosted Google Drive accessible from anywhere | File access |
| Syncthing | Encrypted, continuous P2P file sync protocol. Ensures data (e.g. Obsidian vaults) stays identical and local across all devices without relying on a central server (or SMB) | P2P sync |
| Immich | Photo gallery with AI features for face recognition, semantic search, location maps, and automatic albums (powered by @Salvoxia's immich-album-folder-creator Python script) | AI photo gallery |
| Service | Description | Role |
|---|---|---|
| Vaultwarden | Password manager, replaces or complements 1Password/LastPass | Password management |
| Karakeep | AI-powered bookmark manager (via Ollama), replaces or complements Pocket/Raindrop | Bookmark management |
| SearXNG | Highly customizable metasearch engine. Local Google alternative | Search |
| JDownloader 2 | Multi-source download manager with link decryption and browser extension support | Download manager |
| Service | Description | Role |
|---|---|---|
| Open WebUI | Local alternative to cloud AI services, powered by local models (Ollama) with extensive features (RAG, pipelines, functions, etc.) and deep integration with other local solutions (SearXNG, Perplexica, Qdrant, Ollama, ComfyUI, etc.) | AI GUI |
| Perplexica | Local Perplexity AI alternative | AI search |
| Qdrant | Vector database for semantic search and RAG embeddings | Vector DB |
| Ollama | Local LLM inference runtime — serves models to the entire LAN via AMD ROCm GPU | LLM |
| ComfyUI | Local Midjourney/DALL-E alternative — Stable Diffusion node editor running on AMD GPU | AI image generation |
graph LR
subgraph Workstation ["Desktop - CachyOS"]
GPU[("AMD RX 6700 XT")]
Ollama_svc["Ollama Service"]
Comfy["ComfyUI"]
GPU --- Ollama_svc
GPU --- Comfy
end
subgraph Server ["Home Server - Proxmox VM"]
OWUI["Open WebUI"]
PX["Perplexica"]
end
%% API connections
OWUI <-->|"API :11434"| Ollama_svc
PX <-->|"API :11434"| Ollama_svc
OWUI -->|"Image Gen API"| Comfy
%% User access
User(("User")) -->|"Browser"| OWUI
User -->|"Browser"| Comfy
style GPU fill:#e11,color:#fff
style Ollama_svc fill:#333,color:#fff
style OWUI fill:#00adff,color:#fff
| Service | Description | Role |
|---|---|---|
| Frigate | Replaces cloud NVR subscriptions (Nest/Ring/Arlo) — local AI object detection on security cameras, footage never leaves the network | Surveillance |
| n8n | Zapier/Make replacement — visual workflow automation with 400+ integrations, no subscription required | Automation |
| Service | Description | Role |
|---|---|---|
| Comet | Self-hosted Stremio addon backend for media discovery and debrid integration | Stremio addon |
| Jackett | Unified content indexer aggregator with Cloudflare bypass support | Indexer aggregator |
No cloud subscriptions — everything runs locally The entire stack replaces or complements services that require paid subscriptions: Google Photos (Immich), Google Drive (Samba + Syncthing), ChatGPT/Claude (Ollama + Open WebUI), 1Password (Vaultwarden), Zapier (n8n), GitHub (Forgejo), Perplexity AI (Perplexica), Pocket (Karakeep), Nest/Ring (Frigate). All data stays local under my control.
3-2-1 backup strategy Restic handles encrypted, deduplicated backups at the system level. Each backup job writes to two destinations: the personal workstation (local copy) and Backblaze B2 (offsite cloud copy). This ensures data survives hardware failure, accidental deletion, or ransomware — without relying on a single storage location.
GPU-accelerated local AI Ollama and ComfyUI run on my personal desktop with an RX 6700 XT using ROCm (I use arch btw). Open WebUI connects over LAN to these instances.
Remote access without a cloud middleman All services and files are reachable from anywhere via Tailscale, which routes traffic through the home network instead of a third-party VPN server. Pi-hole handles DNS for the network, so Caddy's custom domains resolve the same way locally and remotely.
Security cameras without cloud exposure Frigate processes camera feeds locally using AI object detection (people, vehicles, animals). Footage is stored on local disks and never uploaded to any cloud service.
Docker network isolation
Each stack uses a dedicated internal: true backend network (e.g., ia_internal, immich_default). Only the web-facing container joins caddy_net. Databases, caches, and workers are never reachable from outside their stack.
Automatic updates with notifications
Watchtower checks for new images daily at 10:00 AM and sends Telegram notifications on updates. All containers use pinned or stable tags; latest only where upstream doesn't provide alternatives.
Encrypted offsite backups Restic encrypts all backup data at rest. Backblaze B2 provides geographic redundancy at ~$6/TB/month — far cheaper than traditional cloud backup services, while still ensuring an offsite copy exists in case of local disaster.
DNS-based service discovery
Caddy resolves backends by Docker container name (e.g., reverse_proxy immich_server:2283). No hardcoded IPs for internal services. Pi-hole wildcard address=/.domain/192.168.0.11 routes all *.domain to Caddy.
Throughout the build-out of this server, I made several decisions based on highly situational criteria — need, practicality, and what I felt like learning at any given moment.
The server started as a simple Open Media Vault setup, but OMV's interface and plugins became increasingly insufficient. Also, the interface didn't always reflect changes made outside of it. Proxmox VE let me learn about virtualization, and its LXC containers gave me the chance to isolate critical but lightweight services.
Kubernetes is the industry standard, but for a single server, Docker Compose is much easier to maintain. I don't need the extra complexity of K8s because I don't have hundreds of servers or auto-scaling needs. I prefer stability and simplicity.
Tailscale lets me access my services securely from anywhere without opening ports on my router. It's safer than exposing a traditional VPN server to the internet.
Its complementarity with Unbound was also a very important factor.
I chose Caddy because it handles HTTPS automatically. With Nginx, I would need to configure Certbot separately and write longer config files. Caddy does the same job with just a few lines.
The Debian VM originally ran Portainer as its Docker manager, but it started feeling heavy, with features I didn't actually use (at least not through Portainer) and disrespectful of my file structures (it creates its own folder for compose files). Dockge and Dozzle instead give me exactly what I need from both tools, while letting me keep whatever file structure I want and even edit files outside of Dockge.
Hardware selection for this homelab follows a philosophy of efficiency and cost-effectiveness, prioritizing system stability and full control over data flow.
1. Main Server (Virtualization Node)
This machine acts as the infrastructure's "brain", running Proxmox VE as hypervisor.
-
CPU: Intel i5 11400F (6 cores / 12 threads)
-
RAM: 16GB DDR4
-
Storage:
-
System & Apps: NVMe SSD for fast response times.
-
Data & Media: 2x HDD for mass storage.
-
Role: Host for virtual machines (Debian/Docker) and LXC containers (Networking).
2. Workstation & AI Inference
My personal workstation, which serves as a high-performance compute node for AI tasks.
OS: Arch based, btw
CPU: Ryzen 5 7600
GPU: AMD Radeon RX 6700 XT (12GB VRAM) — Used for local LLM inference and image generation. The AMD GPU was integrated into the server's workflow to demonstrate a distributed compute environment, where the server requests processing power from the Workstation only when needed.
RAM: 32GB DDR5
3. Network & Perimeter Infrastructure
I opted for a segmented network architecture to maximize control and coverage:
-
Main Router: High-performance Wi-Fi 6 router (Dual-Band). Chosen for its ability to handle multiple data streams and allow custom DNS configuration at the DHCP level. Using a dedicated router separates traffic and improves security beyond what standard ISP equipment can provide.
-
Signal Extension: Wired Gigabit access point, configured to eliminate dead zones and maintain IoT service stability.
-
Physical Security: Wi-Fi security camera with local integration, privately managed to avoid dependency on proprietary clouds.
A homelab is a personal technology environment built at home, where IT professionals and enthusiasts learn and experiment with computer systems. It can range from a simple Raspberry Pi or unused computer to a full set of servers, switches, and networking equipment.
My main goal was to gain more control over my daily devices and tools. Were my personal files truly safe in third-party cloud services?
The shutdown of the popular MegaUpload, which coincided with my teenage years and my first years as an internet user, planted an early distrust. But more ordinary events also contributed, such as:
-
Changes in cloud service pricing.
-
File deletion due to real or fictitious violations of platforms' ever-changing Terms of Service.
I also believe that:
-
virtually no cloud platform guarantees an adequate level of privacy for personal file storage, and
-
a user should never depend on a single option (not even a self-hosted one) for preserving their data (see 3-2-1 backup strategies, for example).
Whenever "replacement" is mentioned here, it can also mean "complementarity". Adopting a solution doesn't mean abandoning another — it means reducing dependency.
Furthermore, I believe that self-hosting services allows and forces users to better understand (and adapt) how those services work and manage their information, contributing to a more authentic exercise of control over both.
In short, this enables: more control and knowledge of our systems, more privacy, lower costs (though this depends on how far one wants to take the hobby).
While this homelab was born to satisfy personal needs and curiosities, different parts of its architecture can be leveraged in larger-scale scenarios.
🏠 Personal and family use
- Storage control: Replace cloud storage services (Google Photos/Drive) with simple solutions like Samba (+ Tailscale for remote access)
- Home security: Manage security cameras with Frigate, processing video locally without sending data to external servers, with better security than proprietary apps and without their payment limits.
- Digital hygiene: Clean browsing free of ads and trackers through Pi-hole's DNS filtering.
- Password management: Replace services like LastPass with Vaultwarden, an open-source, self-hosted alternative.
💼 Small Businesses and SMEs
Many of these solutions allow small organizations to professionalize their infrastructure with minimal licensing costs:
- Secure network infrastructure: The combination of a dedicated router + Tailscale allows connecting branch offices or remote employees with encryption, without complex traditional VPN configurations.
- Asset protection: Deploying Caddy + CrowdSec provides enterprise-grade security (WAF and IPS) to protect websites or internal tools against brute force attacks and bots.
- Private AI and productivity: Deploying Open WebUI + Ollama allows a business to use language models (LLMs) to analyze confidential internal documents without that data leaving their infrastructure or feeding third-party models.
- Surveillance: Deploying Frigate allows monitoring security cameras locally, processing video on the server and storing only relevant events, reducing costs, cloud data load, and improving privacy.
homelab/
├── docker/
│ ├── beszel/ # Monitoring
│ ├── caddy-crowdsec/ # Caddyfile + compose (reverse proxy + WAF)
│ ├── comfyui/ # Image generation (local, ROCm6)
│ ├── dockge/ # Docker Compose web manager
│ ├── dozzle/ # Real-time container log viewer
│ ├── forgejo/ # Git service
│ ├── frigate/ # NVR + AI object detection
│ ├── homepage/ # Service dashboard
│ ├── ia-stack/ # Open WebUI, Perplexica, SearXNG, Qdrant, Redis
│ ├── immich/ # AI photo gallery
│ ├── jdownloader-2/ # Download manager
│ ├── karakeep/ # AI bookmarks
│ ├── n8n/ # Workflow automation
│ ├── ollama/ # LLM inference (local, AMD ROCm)
│ ├── samba/ # SMB file shares
│ ├── stremio-stack/ # Comet, Jackett
│ ├── syncthing/ # P2P sync
│ ├── vaultwarden/ # Password manager
│ └── watchtower/ # Automatic updates
├── .gitignore
├── README.md
└── README.es.md
Each directory contains a compose.yml (or docker-compose.yaml) with the service configuration. Secrets are managed via .env files excluded by .gitignore.