Home server infrastructure overview
I’ve been running a home server for over 10 years, and it’s evolved significantly over time. It all started with an old desktop PC running Debian, acting as a NAS and Minecraft server. Today, my setup is much more complicated.
My current setup includes:
- Proxmox VE as the virtualization host
- Debian 12 virtual machines (VMs)
- Ansible for configuring VMs and deploying applications
- Applications running in Docker containers
- Nginx for reverse proxy and SSL termination
- Local DNS names using my own domain
- Let’s Encrypt SSL certificates for local services
- WireGuard VPN for secure remote access
Server
The server runs on second-hand enterprise hardware, which has proven reliable. The key specs are:
- CPU: 2x AMD Opteron 6278
- Motherboard: Asus KGPE-D16
- RAM: 128 GB DDR3 ECC
- NIC: Mellanox ConnectX-3 10GbE
- Storage Controller: LSI SAS2308 SAS
My storage setup consists of:
- 960 GB Kingston DC600M for the boot drive
- 8x 4TB HGST drives in a ZFS RAIDZ2 pool for NAS storage
- 2x 2TB Samsung 970 Evo Plus in a ZFS mirror pool for VM storage
- 2TB HDD for VM backups
I use ZFS for both NAS and VM storage due to its reliability and built-in snapshot capabilities. The NAS pool is shared via NFS, and all VMs are backed up daily to the 2TB HDD using Proxmox’s built-in backup feature.
Software and Services
I currently host several services on my home server, including:
- Unbound (local DNS server)
- Jellyfin (media streaming)
- Navidrome (self-hosted Spotify alternative)
- Gitea (private git repository hosting)
- Prometheus and Grafana (monitoring and visualization)
Proxmox VE
For virtualization, I’m running Proxmox VE, a Debian-based platform that includes built-in support for the ZFS filesystem. Proxmox has been my go-to solution for over 5 years for managing virtual machines.
Virtual Machines
All services are hosted on Debian 12 virtual machines. I use a Debian 12 cloud image as the base OS for each VM. Cloud-init is used for network configuration and SSH key setup, making it simple to clone templates and deploy new VMs quickly. In the future, I plan to start deploying the VMs using Terraform.
Ansible
I use Ansible to handle configuration and deployment tasks. I’ve created a base role that applies to every VM, which includes installing common software, setting up firewall rules, performing optimizations and hardening. All actual applications that I host are also deployed using Ansible.
Docker
All applications run inside Docker containers on the VMs. I deploy the containers using Ansible, it makes deploying and uppgrading containers as simple as updating the tag and running the playbook. I am currently use Docker as the container runtime, but I’m considering switching to Podman, which I already use on my workstations.
Networking and Security
Firewall Configuration
I use UFW to manage firewall rules across VMs. I use Ansible to deploy the firewall rules. The firewall is configured to allow only SSH access from the LAN and the VPN server, with all other incoming traffic denied by default.
Nginx for Reverse Proxy and SSL
Each VM hosting a web application uses Nginx as a reverse proxy, which also handles the SSL certificates.
Local DNS and SSL certificates
I use Unbound as my local DNS server. I have assigned DNS entries like servicename.domain.tld
to each of my self-hosted services.
I use Let’s Encrypt to obtain SSL certificates for my self-hosted services. A dedicated VM runs the getssl script, using the DNS verification method to obtain wildcard certificates (as I don’t have a static IP). These certificates are then distributed to all VMs that need them.
Future improvements
- Switch from Docker to Podman
- Start using Hashicorp Vault for storing SSL certificates and other secrets
- Use Terraform to deploy VMs