My Homeserver & VPS

Overview

This is where I document my journey into self-hosting and infrastructure. I run a homeserver at home with a dual-path setup for exposing services.

Why self-host at all?
  • Control: My data stays on my hardware
  • Learning: Hands-on experience with networking, Linux, Docker
  • Cost: Long-term, most services are cheaper to self-host
  • Fun: It's a hobby that actually produces useful things

The Setup

Hardware

  • Homeserver: — NUC 13 Pro with an i5-1340P and 16 GB DDR4 RAM
  • VPS: — Oracle's Always Free Tier; it has great value :)

Network Architecture

I use a dual-path approach to expose my services:

                                    HOMESERVER
      ┌───────────────────────────────────────────────────────────┐
      │    ┌────────────┐    ┌─────────────┐    ┌────────────┐    │
      │    │  Web Apps  │    │ Gameserver  │    │   Other    │    │
      │    │  (Tunnel)  │    │ (VPS Path)  │    │  Services  │    │
      │    └────────────┘    └─────────────┘    └────────────┘    │
      └───────────┬────────────────────────────────┬──────────────┘
                  │                                │
                  │ Primary Path                   │ Secondary Path
                  │ (HTTP/HTTPS)                   │ (non-HTTP, Games)
                  ▼                                ▼
      ┌───────────────────────┐        ┌───────────────────────┐
      │      Cloudflare       │        │    VPS + WireGuard    │
      │   (Tunnel + Proxy)    │        │     (public IP)       │
      └───────────────────────┘        └───────────────────────┘
        

Path 1: Cloudflare Tunnel (Primary)

Most services go through Cloudflare Tunnels — no ports to open and free DDoS protection.

Why Cloudflare Tunnel as primary?
  • No port forwarding: Works behind any NAT/firewall
  • DDoS protection: Cloudflare absorbs attacks
  • Static home IP not needed: Tunnel handles dynamic IPs
  • Proxy benefits: Caching, WAF, analytics

The tunnel creates an outbound-only connection, so I have no open ports — even if I wanted to, I couldn't open ports due to CGNAT.

Path 2: WireGuard + VPS (Secondary)

For services that Cloudflare doesn't allow or can't handle (non-HTTP traffic like game servers), I route through my VPS via WireGuard.

When do I use the VPS path?
  • Game servers: UDP traffic, custom ports
  • Non-HTTP services: Mail, FTP, custom protocols
  • High-bandwidth: Video streaming, large file transfers (violates Cloudflare TOS)
  • Unrestricted ports: Cloudflare Tunnel only supports certain ports

The VPS has a static public IPv4 and forwards traffic through WireGuard to my homeserver. In both cases, my home IP is hidden.


Services I Run

Currently Running

  • AdGuard Home: — Network-wide ad blocking and DNS filtering
  • Traefik: — Reverse proxy with automatic HTTPS via Let's Encrypt
  • Cloudflare Tunnel: — Zero-trust access without port forwarding
  • WireGuard: — VPN tunnel between VPS and homeserver (non-dockerized)
  • Obsidian LiveSync: — Self-hosted sync with CouchDB
  • Portainer: — Container management UI

Most services run as Docker Compose stacks, except WireGuard which runs natively.

Planned

  • [ ] Homepage dashboard
  • [ ] Uptime Kuma

Deep Dives

Detailed guides for complex setups:

  • AdGuard Home Setup — DNS filtering, blocklists, network integration
  • WireGuard: VPS ↔ Homeserver — Hub-and-spoke VPN, Port-Forwarding, Split-Tunnel
  • Traefik Reverse Proxy — HTTPS, Let's Encrypt, and routing (coming soon)
  • Cloudflare Tunnel — Zero-trust tunnel setup without port forwarding (coming soon)
  • Obsidian LiveSync — Self-hosted Obsidian sync with CouchDB (coming soon)

Lessons Learned

  • Document as you go, not "later" because later never comes.
  • Expose only what you use; keep the rest private.
  • Small, reversible changes are easier to debug than big rewrites.
  • It's remarkable how the Internet just works. You can use it every day without knowing all the inner details.

Future Plans

  • [ ] Automated encrypted backups
  • [ ] Write deep dive guides
  • [ ] Document setup on website