Home Infrastructure

Dec 26, 2025 4 mins read


Overview

A complete infrastructure-as-code setup managing multiple servers and services from a single repository. This project orchestrates over 17 containerized services including authentication, IoT automation, monitoring, remote access, and more across both a production VPS and edge devices.

Motivation

I got tired of manually configuring services every time something broke or when I wanted to try something new. You know the drill - SSH into a server, run some commands, edit some config files, hope you remember what you did when it inevitably breaks next month. It gets old fast.

I wanted a way to manage everything declaratively. If a server dies, I should be able to spin up a new one and get everything running again with a single command. If I mess something up, I should be able to roll back easily. And most importantly, I wanted to learn how real infrastructure is managed in production environments.

Cloud providers make this easy but expensive. Running all these services on AWS or GCP would cost hundreds of dollars a month. Instead, I invested in a VPS and some local hardware, and built my own automation around it. Now I have full control, it costs me about less than 2 coffees this days, and I’ve learned a ton about infrastructure management in the process.

What It Runs

The infrastructure currently manages:

  • Authentication - Authentik for SSO across all services (Mostly deprecated using gcp SSO instead)
  • IoT Automation - Node-RED, InfluxDB, Mosquitto MQTT broker
  • Monitoring - Grafana with OAuth2 protection
  • Remote Access - Guacamole for accessing my home machines
  • Password Management - Vaultwarden (self-hosted Bitwarden)
  • Workflow Automation - n8n for connecting services
  • Container Management - Portainer for Docker UI
  • Reverse Proxy - Traefik handling SSL/TLS and routing

All services are protected by OAuth2 where appropriate and accessible via proper domain names with automatic SSL certificates through Cloudflare.

You can see the full dashboard at homer.vultur.josnelihurt.me.

Technical Stack

The setup uses a layered approach:

  • Docker Compose - Service definitions and container orchestration
  • Ansible - Remote deployment and configuration management
  • Traefik - Reverse proxy with automatic SSL/TLS via Let’s Encrypt
  • Bash Scripts - User-friendly deployment wrappers organized by server
  • Git - Version control for infrastructure code

Each service follows consistent patterns: isolated Docker networks, centralized logging with size limits (learned that lesson the hard way when logs filled up the disk), OAuth2 protection for sensitive services, and health checks for deployment verification.

Architecture Approach

Everything is organized by target server. The services/ directory contains subdirectories for each server, and deployment scripts are similarly organized. When you want to deploy something, you run a script like ./scripts/vultur/deploy_iot.sh and it handles:

  1. Loading secrets from a gitignored .secrets directory
  2. Syncing the repository to the remote server
  3. Running the appropriate Ansible playbook
  4. Deploying via Docker Compose on the remote server
  5. Verifying containers are healthy

This means I can deploy to production from my laptop, from a CI/CD pipeline, or even from my phone in a pinch. The entire state of my infrastructure lives in git, except for secrets which are managed separately (yeah plain files for now, maybe one day I can use something more secure than that lol).

What I Learned

This project taught me more about real-world infrastructure than any tutorial could. Some highlights:

  • Docker networking is more complex than it seems when you start having services that need to talk to each other across multiple networks
  • Logging limits are not optional - I had Node-RED logs grow to 2.5GB and fill my disk because of a write loop, this wouldn’t show up as quickly in a local environment with more space but my cloud vm small due to my budget.
  • OAuth2 cookie secrets must be exactly 16, 24, or 32 bytes or you’ll spend hours debugging 404 errors
  • Ansible is powerful but the learning curve is real
  • Infrastructure as code is worth the upfront investment - I’ve rebuilt servers multiple times and it takes minutes instead of hours

The infrastructure continues to evolve as I add new services or improve existing patterns. Having everything in code means I can experiment freely - if something breaks, I just roll back to the previous commit.