106 lines
4.8 KiB
Plaintext
106 lines
4.8 KiB
Plaintext
# Self-Hosted Git Service – Public Architecture
|
||
|
||
## Overview
|
||
|
||
A self-hosted Gitea instance running on a home server, made publicly accessible via a cheap VPS (1 vCPU, 1 GB RAM, 10 GB SSD) acting as a secure entry point.
|
||
|
||
## Architecture
|
||
|
||
```
|
||
Internet
|
||
│
|
||
▼
|
||
┌─────────────────────┐
|
||
│ VPS (Debian) │
|
||
│ Public IPv4 │
|
||
│ │
|
||
│ WireGuard Tunnel │
|
||
│ iptables NAT │
|
||
│ (Port 80/443 →) │
|
||
└─────────┬───────────┘
|
||
│
|
||
WireGuard Tunnel
|
||
(encrypted, UDP)
|
||
│
|
||
▼
|
||
┌───────────────────────────────┐
|
||
│ Home Network │
|
||
│ │
|
||
│ ┌─────────────────────────┐ │
|
||
│ │ LXC: Reverse Proxy │ │
|
||
│ │ │ │
|
||
│ │ Caddy │ │
|
||
│ │ - Auto TLS (Let's Enc.) │ │
|
||
│ │ - Reverse Proxy → Gitea │ │
|
||
│ └────────────┬────────────┘ │
|
||
│ │ │
|
||
│ LAN Bridge │
|
||
│ │ │
|
||
│ ┌────────────▼────────────┐ │
|
||
│ │ LXC: Gitea │ │
|
||
│ │ │ │
|
||
│ │ Git Hosting (HTTPS) │ │
|
||
│ │ Web UI + API │ │
|
||
│ └─────────────────────────┘ │
|
||
│ │
|
||
│ Proxmox VE Host │
|
||
└───────────────────────────────┘
|
||
```
|
||
|
||
## Traffic Flow
|
||
|
||
1. User visits `https://git.example.com`
|
||
2. DNS resolves to VPS public IP
|
||
3. VPS forwards port 80/443 through WireGuard tunnel via iptables NAT
|
||
4. Caddy (in LXC) terminates TLS with auto-provisioned Let's Encrypt certificate
|
||
5. Caddy reverse-proxies request to Gitea (LXC) over LAN
|
||
6. Gitea serves the response back through the same path
|
||
|
||
## Components
|
||
|
||
| Component | Role | Environment |
|
||
|-----------|------|-------------|
|
||
| VPS (1€/month) | Public entry point, WireGuard endpoint, port forwarding | Debian, cloud-hosted |
|
||
| WireGuard | Encrypted site-to-site tunnel between VPS and home network | Both sides |
|
||
| Caddy | Reverse proxy with automatic HTTPS (Let's Encrypt) | LXC on Proxmox |
|
||
| Gitea | Self-hosted Git service (web UI, API, HTTPS clone) | LXC on Proxmox |
|
||
| Proxmox VE | Hypervisor managing all local containers | Bare-metal, home server |
|
||
|
||
## Design Decisions
|
||
|
||
**WireGuard over Tailscale/Headscale**
|
||
Only two endpoints with a fixed public IP on the VPS side – a simple point-to-point WireGuard tunnel is sufficient. No need for mesh networking, NAT traversal, or a coordination server. Tailscale/Headscale can be added later if the setup grows.
|
||
|
||
**Caddy over NGINX**
|
||
Caddy provides automatic TLS certificate provisioning and renewal with zero configuration. The entire reverse proxy config is 6 lines.
|
||
|
||
**Reverse Proxy in separate LXC**
|
||
Keeps the proxy isolated from both the hypervisor and the application. Adding new services only requires editing the Caddyfile – no changes to the VPS or tunnel needed.
|
||
|
||
**TLS termination at home, not on VPS**
|
||
The VPS only forwards encrypted traffic. TLS is terminated by Caddy in the home network, keeping certificate management local and the VPS stateless.
|
||
|
||
## Extensibility
|
||
|
||
Adding a new public service requires three steps:
|
||
|
||
1. Deploy the service on Proxmox (VM or LXC)
|
||
2. Add a DNS A-record pointing to the VPS
|
||
3. Add a `reverse_proxy` block to the Caddyfile:
|
||
```
|
||
newservice.example.com {
|
||
reverse_proxy <local-ip>:<port>
|
||
}
|
||
```
|
||
|
||
No changes to the VPS, tunnel, or firewall needed.
|
||
|
||
## Security
|
||
|
||
- VPS has no application logic – it only forwards traffic
|
||
- WireGuard provides authenticated, encrypted communication between sites
|
||
- TLS certificates are automatically managed by Caddy (Let's Encrypt)
|
||
- Gitea is not directly exposed to the internet
|
||
- SSH hardened: key-only authentication, no root login
|
||
- VPS firewall managed at provider level (only SSH, HTTP, HTTPS, WireGuard open)
|