Skip to content

VPS Architecture

Cloud node for Tailscale coordination, monitoring, and external services — minimal personal data at rest. 12 containers running 24/7.

Key principle: Headscale runs on VPS for 24/7 mesh availability. Mobile kit operates on-demand (7AM-7PM). If VPS dies, mesh clients still work with cached keys but can't add new nodes.

Goals

  • 24/7 Tailscale mesh coordination
  • External monitoring of homelab
  • Privacy/sovereignty preserved (data stays at home)
  • US IP for web scraping
  • ~$6/month budget

Provider

Provider Plan Specs Price
Vultr High Frequency 1 vCPU, 1GB RAM, 32GB NVMe $6/mo

Location: USA (for web scraping and low latency)

Services

Tier 1: Network Infrastructure

Service Port Purpose Status
Headscale 8080 Tailscale coordination server Active
Caddy 80, 443 Reverse proxy, auto-SSL Active

Tier 2: Monitoring

Service Port Purpose Status
Uptime Kuma 3001 Status monitoring Active
ntfy 80 Push notifications Active

Tier 3: Utilities

Service Port Purpose Status
changedetection.io 5000 Website change monitoring Active
Playwright Browser engine for changedetection Active
DERP Relay 3478/udp Tailscale NAT traversal Active
Restic REST Server 8000 Encrypted backup target Active
AdGuard Home (Yvága) 53, 3000 DNS ad-blocking + filtering Active
Unbound (Yvága) 5335 Recursive DNS resolver Active
Pi-hole (VPS) 53 DNS (legacy, secondary) Active

Architecture Diagram

                        [Internet]
                            |
                     [Vultr VPS - US]
                      <VPS_PUBLIC_IP>
                      100.77.172.46 (TS)
                            |
    +------------+----------+----------+------------+----------+
    |            |          |          |            |          |
[Headscale]  [Caddy]  [Uptime Kuma]  [ntfy]    [DERP]   [Yvága]
(TS coord)  (proxy)   (monitoring) (alerts)  (relay)  (AdGuard+Unbound)
                            |
                     [Tailscale Mesh]
                            |
        +-------------------+-------------------+
        |                   |                   |
   [Mobile Kit]        [Devices]         [Fixed Homelab]
   Beryl AX + RPi 5    MacBook, Phone    Proxmox + Docker VM

Flow: VPS Headscale coordinates mesh. All devices connect via Tailscale. VPS acts as exit node when needed.

Endpoints

Subdomain Service Notes
hs.cronova.dev Headscale Tailscale coordination
status.cronova.dev Uptime Kuma Public status page
notify.cronova.dev ntfy Push notifications
cronova.dev Landing page Static HTML

Privacy Model

What VPS Sees

  • Tailscale mesh metadata (which devices are online)
  • Which websites you monitor for uptime
  • Notification content (you control what's sent)

What VPS Never Sees

  • Actual file contents from home
  • Traffic between mesh devices (WireGuard encrypted)
  • Passwords, documents, media

Trust Level: Moderate

  • VPS is assumed potentially compromised
  • No sensitive data at rest
  • Mesh traffic is end-to-end encrypted

Docker Structure

docker/vps/
├── networking/
│   ├── headscale/
│   │   ├── docker-compose.yml
│   │   ├── backup.sh
│   │   └── config/
│   ├── caddy/
│   │   ├── docker-compose.yml
│   │   ├── Caddyfile
│   │   └── www/
│   ├── adguard/              # AdGuard Home + Unbound (Yvága)
│   │   └── docker-compose.yml
│   ├── derp/                 # DERP relay
│   │   └── docker-compose.yml
│   └── pihole/               # Pi-hole (VPS, legacy)
│       └── docker-compose.yml
├── monitoring/
│   └── docker-compose.yml    # Uptime Kuma, ntfy
├── scraping/
│   └── docker-compose.yml    # changedetection, Playwright
└── backup/
    └── docker-compose.yml    # Restic REST Server

Deployment Status

Phase Task Status
1 Create Vultr account, deploy VPS Done
2 Basic hardening (SSH keys, firewall) Done
3 Install Docker Done
4 Deploy Headscale Done
5 Deploy Caddy reverse proxy Done
6 Deploy Uptime Kuma Done
7 Deploy ntfy Done
8 Deploy changedetection.io Done
9 Configure DERP relay Done
10 Deploy AdGuard + Unbound (Yvága) Done
11 Deploy Pi-hole (VPS) Done
12 Deploy Restic REST Server Done

Security Hardening

  • SSH key auth only (no password)
  • UFW firewall (only needed ports)
  • Fail2ban for SSH
  • Automatic security updates
  • No root login
  • Tailscale for private service access

Backup Strategy

  • Headscale: Hourly backup via sidecar container
  • Backup location: /home/linuxuser/backups/headscale/
  • See docker/vps/networking/headscale/backup.sh

Cost

Item Monthly
Vultr VPS (1GB) $6.00
Domain (cronova.dev) ~$1.00
Total ~$7.00

Future Enhancements

  • [ ] Grafana for VPS metrics

References