The Problem
Cloud infrastructure is expensive for personal projects and learning environments. I needed a platform to run production-quality services, experiment with new technologies, and demonstrate real operational skills — not just “hello world” deployments.
The Solution
A multi-host Docker infrastructure running enterprise-grade tooling: reverse proxy with automatic TLS, centralized authentication, full observability pipeline, automated security scanning, and CI/CD — all managed as Infrastructure as Code.
Network Architecture
- 4 physical hosts across a 172.16.0.0/16 network
- Traefik reverse proxy with wildcard Let’s Encrypt TLS via Route53 DNS challenge
- WireGuard VPN for secure remote access
- UniFi network management with VLAN segmentation
Observability Stack
The monitoring pipeline provides full visibility into every layer:
- Prometheus — metrics collection from all hosts and containers
- Grafana — dashboards for infrastructure health, container performance, and network traffic
- Loki + Alloy — centralized log aggregation with structured JSON logging
- Uptime Kuma — 28 service monitors with email alerting
- cAdvisor — container resource utilization metrics
- SNMP Exporter — network equipment monitoring (switches, APs, NAS)
Security Layers
- CrowdSec — WAF + IPS with community threat intelligence
- Trivy — daily CVE scanning of all running container images with HTML reports and email alerts
- Authentik SSO — centralized authentication with Google OAuth, OIDC, and forward-auth
- Automated backup verification — weekly integrity checks on all Restic repositories
CI/CD Pipeline
- GitHub Actions — lint, test, build, and SonarQube scans on every push
- Woodpecker CI — automated deployments via SSH on cron/webhook
- Self-hosted runners — 8 dedicated GitHub Actions runners for private repos
- SonarQube — static analysis for code quality across all projects
Key Design Decisions
- Separate compose stacks per logical group — not one per container, not a monolith
- All services get Traefik labels + Alloy logging labels — consistent discoverability
- Secrets in .env files, never committed — with .env.example templates
- SMB for shared storage — reliability over NFS complexity
- Docker Compose as IaC — version-controlled, reproducible deployments
Results
- 99.9% uptime across all critical services (measured over 6+ months)
- Mean time to recovery under 5 minutes (automated restarts + alerting)
- Zero security incidents (CrowdSec + Trivy + SSO defense in depth)
- Full disaster recovery capability via automated Restic backups (daily, verified weekly)