Self-Hosting on Hetzner: My Complete €15/month Infrastructure Stack
I run 15+ services on a single Hetzner server for €15/month. Everything is GDPR-compliant because all data stays in Germany. Here's the full stack.
The Server
Hetzner CX32 (or equivalent):
- 2 vCPU, 8GB RAM
- 80GB SSD
- €15/month
- Location: Falkenstein, Germany 🇩🇪
This is enough to run everything a small business needs.
The Stack
| Service | Purpose | Replaces |
|---|---|---|
| Nginx Proxy Manager | Reverse Proxy + SSL | Cloudflare, AWS ALB |
| Nextcloud | File Sync & Share | Google Drive, Dropbox |
| Matomo | Web Analytics | Google Analytics |
| Vaultwarden | Password Manager | 1Password, Bitwarden Cloud |
| n8n | Workflow Automation | Zapier ($20-600/mo) |
| Uptime Kuma | Monitoring | Pingdom, UptimeRobot |
| Paperless-ngx | Document Management | Google Docs |
| Gitea | Git Hosting | GitHub |
| Portainer | Docker Management | — |
| SearXNG | Private Search | Google Search |
| Roundcube | Webmail | Gmail |
Docker Compose Structure
I organize services into individual docker-compose.yml files in /opt/services/:
/opt/services/
├── proxy/docker-compose.yml
├── nextcloud/docker-compose.yml
├── matomo/docker-compose.yml
├── vaultwarden/docker-compose.yml
├── n8n/docker-compose.yml
├── uptime-kuma/docker-compose.yml
└── paperless/docker-compose.yml
Each service gets its own Docker network. Nginx Proxy Manager sits in front and handles SSL termination.
Key Security Hardening
1. UFW Firewall (BUT Watch Out for Docker!)
Docker bypasses UFW by default. This is a common gotcha.
# Check what's actually exposed
ss -tlnp | grep 0.0.0.0
# Fix: Edit /etc/docker/daemon.json
{
"iptables": false
}
# Then manage ALL firewall rules via UFW
2. SSH Hardening
# /etc/ssh/sshd_config
PermitRootLogin prohibit-password
PasswordAuthentication no
Port 2222 # Non-standard port reduces noise
MaxAuthTries 3
3. Fail2ban
apt install fail2ban
systemctl enable fail2ban
Default config bans after 5 failed attempts for 1 hour.
4. Automatic Updates
apt install unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades
5. Backup Strategy
#!/bin/bash
# daily-backup.sh
DATE=$(date +%Y-%m-%d)
pg_dumpall | gzip > /root/backups/$DATE/db.sql.gz
tar czf /root/backups/$DATE/services.tar.gz /opt/services/
find /root/backups/ -mtime +7 -delete
Cron: 0 4 * * * /root/scripts/daily-backup.sh
GDPR Compliance Checklist
Since everything runs in Falkenstein, Germany:
- ✅ Data never leaves the EU
- ✅ No US cloud services processing personal data
- ✅ Full control over data retention
- ✅ Can fulfill data subject requests (export, delete) immediately
- ✅ No third-party data processing agreements needed (except Hetzner as infrastructure provider)
Cost Comparison
| Service | Cloud Cost | Self-Hosted Cost |
|---|---|---|
| Google Drive (2TB) | €10/mo | €0 (included) |
| 1Password (family) | €4/mo | €0 |
| Zapier (professional) | €20/mo | €0 |
| Google Analytics 360 | €150K/yr | €0 |
| Pingdom | €15/mo | €0 |
| Total | €49+/mo | €15/mo (server) |
Savings: €34+/month, plus full GDPR compliance and data sovereignty.
Monitoring
I use Uptime Kuma to monitor all services. If anything goes down, I get a Telegram notification immediately.
Want to know if your current website setup is GDPR-compliant? Run a free scan — it checks for Google Analytics, external fonts, missing legal pages, and more.
Top comments (0)