Files
pi_mcps/plans/homelab-proxy-architecture.md
T

8.7 KiB

Homelab Proxy Architecture Plan

plate.software VPS as public face → WireGuard tunnel → TrueNAS.local

Goal

Use the cheap public VPS (plate.software @ 85.214.154.199 / Plesk) as:

  • Public DNS + TLS termination point
  • Apache reverse proxy routing subdomains to TrueNAS homelab services
  • ACME/Let's Encrypt managed by Plesk (already working)

TrueNAS.local (192.168.188.119) becomes the actual compute host for all Docker services.


The Core Problem: TrueNAS is Behind NAT

TrueNAS lives on a home network. The public VPS cannot reach it directly. A tunnel is required.

⚠️ WireGuard NOT possible — VPS is OpenVZ

The VPS (h2970715.stratoserver.net, Strato) runs on OpenVZ virtualization. WireGuard requires a kernel module — not loadable in OpenVZ containers.

Internet
    ↓ DNS
plate.software VPS (85.214.154.199)
    frps server (port 7000)
    ↓ Apache ProxyPass (HTTP/HTTPS)
    ↓ frp tunnel (TCP, userspace)
TrueNAS.local (192.168.188.119)
    frpc client → connects out to VPS:7000
    ├── Gitea           :30008  →  git.plate.software → VPS:30008
    ├── WildFly/Java EE :8080   →  plate.software     → VPS:18080
    └── Future services :XXXX  →  app.plate.software

Why frp:

  • Pure userspace Go binary — works perfectly on OpenVZ
  • TrueNAS (frpc) initiates outbound connection — no router port forwarding needed
  • Encrypted tunnel (TLS optional)
  • VPS (frps) exposes local ports that Apache proxies to
  • Zero kernel dependencies

Target DNS Routing

Domain / Subdomain Routes to Notes
plate.software TrueNAS:8080 (WildFly) Current customer Java EE project
git.plate.software TrueNAS:30008 (Gitea) New — expose homelab Gitea publicly
app.plate.software TrueNAS:XXXX (future) Placeholder for future projects

All DNS A records point to 85.214.154.199 (VPS). TLS is terminated at the VPS by Plesk/Let's Encrypt.


Implementation Steps

Phase 1: WireGuard Tunnel (VPS ↔ TrueNAS)

On the VPS (root@85.214.154.199):

apt install wireguard
wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key

Create /etc/wireguard/wg0.conf:

[Interface]
Address = 10.100.0.1/24
ListenPort = 51820
PrivateKey = <server_private_key>

[Peer]
PublicKey = <truenas_public_key>
AllowedIPs = 10.100.0.2/32
PersistentKeepalive = 25

On TrueNAS (via TrueNAS SCALE UI or shell):

  • Apps → Network → WireGuard → Add Interface
  • Or via shell: same wg genkey + /etc/wireguard/wg0.conf approach
[Interface]
Address = 10.100.0.2/24
PrivateKey = <truenas_private_key>

[Peer]
PublicKey = <vps_public_key>
Endpoint = 85.214.154.199:51820
AllowedIPs = 10.100.0.1/32
PersistentKeepalive = 25

Enable on both:

systemctl enable --now wg-quick@wg0

Test:

# From VPS
ping 10.100.0.2
curl http://10.100.0.2:30008  # Should reach Gitea

Phase 2: Firewall — Open WireGuard Port on VPS

# On VPS
ufw allow 51820/udp
# Or via iptables if ufw not present
iptables -A INPUT -p udp --dport 51820 -j ACCEPT

Also ensure TrueNAS router/firewall does NOT need any port forwarding — TrueNAS initiates the tunnel outbound. The VPS listens; TrueNAS connects. No router config needed.


Phase 3: Plesk Apache — Add Subdomain Proxy Rules

Add git.plate.software as a subdomain in Plesk:

  1. Plesk → Domains → Add Subdomain → git.plate.software
  2. Apache & nginx Settings → Additional directives for HTTP:
<IfModule mod_proxy.c>
    ProxyPass /.well-known/acme-challenge/ !
    ProxyPass / http://10.100.0.2:30008/ retry=0
    ProxyPassReverse / http://10.100.0.2:30008/
    ProxyPreserveHost On
</IfModule>
  1. Issue Let's Encrypt cert for git.plate.software
  2. Configure HTTPS redirect and HTTPS proxy directives the same way

Update plate.software HTTP directives: Change the existing WildFly proxy target from 127.0.0.1:8080 to 10.100.0.2:8080 once WildFly is moved to TrueNAS:

ProxyPass / http://10.100.0.2:8080/ retry=0

(Keep this as 127.0.0.1:8080 while the Docker container still runs on the VPS)


Phase 4: Migrate WildFly to TrueNAS

The customer's Java EE app currently runs in Docker on the VPS. Migrate to TrueNAS:

  1. Export/pull the WildFly Docker image
  2. Copy any persistent volumes/data
  3. Create docker-compose.yml on TrueNAS
  4. Start container on TrueNAS, verify on 10.100.0.2:8080
  5. Update VPS Apache proxy target from 127.0.0.1:808010.100.0.2:8080
  6. Remove the Docker container from VPS

Phase 5: Gitea Public HTTPS

For Gitea to work properly behind a proxy, update its config to know its public URL:

Edit Gitea's app.ini (in the Gitea Docker volume on TrueNAS):

[server]
DOMAIN           = git.plate.software
ROOT_URL         = https://git.plate.software/
HTTP_PORT        = 30008

Also in Plesk HTTPS directives for git.plate.software:

<IfModule mod_proxy.c>
    ProxyPass /.well-known/acme-challenge/ !
    ProxyPass / http://10.100.0.2:30008/ retry=0
    ProxyPassReverse / http://10.100.0.2:30008/
    ProxyPreserveHost On
    RequestHeader set X-Forwarded-Proto "https"
    RequestHeader set X-Forwarded-Port "443"
</IfModule>

Network Topology (Final State)

┌─────────────────────────────────────┐
│  Internet / DNS                     │
│  *.plate.software → 85.214.154.199  │
└──────────────┬──────────────────────┘
               │ HTTP/HTTPS
               ▼
┌─────────────────────────────────────┐
│  VPS: plate.software                │
│  85.214.154.199 / Plesk / Apache    │
│                                     │
│  plate.software      → proxy:8080  │
│  git.plate.software  → proxy:30008 │
│  app.plate.software  → proxy:XXXX  │
└──────────────┬──────────────────────┘
               │ WireGuard 10.100.0.0/24
               │ UDP 51820 (encrypted)
               ▼
┌─────────────────────────────────────┐
│  TrueNAS.local                      │
│  192.168.188.119 / WG: 10.100.0.2  │
│                                     │
│  :30008  Gitea                      │
│  :8080   WildFly (Java EE)          │
│  :XXXX   Future services            │
└─────────────────────────────────────┘

Risks & Notes

Risk Mitigation
Home ISP outage takes down all services Acceptable for homelab; add health check monitoring later
ISP dynamic IP changes (if applicable) WireGuard peer config uses VPS as endpoint (fixed IP) — TrueNAS initiates tunnel, so home IP change is transparent
TrueNAS reboot drops tunnel systemctl enable wg-quick@wg0 ensures auto-start
Gitea SSH cloning (port 22/2222) Need separate SSH port forward or Gitea SSH over different port — HTTP clone still works via HTTPS proxy
Customer data on VPS → TrueNAS migration Do at off-peak time; test thoroughly before cutting DNS

Cost Model

  • VPS (plate.software): Keep cheap (~3-5€/month) — CPU/RAM irrelevant, just proxy traffic
  • TrueNAS: All compute happens here — free (already owned hardware)
  • Cloudflare (optional): Free plan for DNS + DDoS protection on top of the VPS

Alternative: Cloudflare Tunnel (Zero-Config Option)

If WireGuard setup is too complex, Cloudflare Tunnel (cloudflared) is a zero-config alternative:

  • Run cloudflared as a Docker container on TrueNAS
  • No VPS needed for tunneling — Cloudflare handles the public endpoint
  • Free for personal use
  • TrueNAS → Cloudflare edge → DNS → users

Downside: Traffic routes through Cloudflare (not self-hosted end-to-end). VPS still useful for non-Cloudflare domains and the existing customer project.


Implementation Priority

  1. Fix plate.software Let's Encrypt (done)
  2. 🔜 Set up WireGuard tunnel (VPS ↔ TrueNAS)
  3. 🔜 Add git.plate.software subdomain in Plesk + proxy to TrueNAS Gitea
  4. 🔜 Update Gitea app.ini with public URL
  5. 🔜 Issue Let's Encrypt for git.plate.software
  6. Migrate WildFly customer project from VPS → TrueNAS
  7. Decommission VPS Docker container (keep VPS as pure proxy)