====== Tutorial: Host a Local Website via VPS with WireGuard and Nginx ======
This tutorial explains how to host a website locally, while making it accessible
through your domain on a VPS. The VPS acts as a reverse proxy and forwards traffic
over a WireGuard tunnel to your home server.
===== Architecture Overview =====
The following diagram illustrates how requests flow from the internet
to your locally hosted website via the VPS and WireGuard tunnel:
+-------------------+
| Client Browser |
| (User requests) |
+---------+---------+
|
v
+-------------------+
| Domain (DNS) |
| mond-keks.de |
+---------+---------+
|
v
+-------------------+
| VPS (Public IP) |
| Nginx Reverse |
| Proxy + SSL |
+---------+---------+
|
| WireGuard Tunnel
v
+-------------------+
| Home Server |
| Local Website |
| (HTTP on 8080) |
+-------------------+
===== Requirements =====
* VPS with public IPv4/IPv6 address
* Home server with IPv6 (e.g. Fritzbox)
* Domain pointing to the VPS IP
* Installed WireGuard and Nginx
===== Step 1: Install WireGuard =====
sudo apt update
sudo apt install wireguard
===== Step 2: Generate Keys =====
wg genkey | tee vps_private.key | wg pubkey > vps_public.key
wg genkey | tee local_private.key | wg pubkey > local_public.key
===== Step 3: Create Configuration =====
VPS: '''/etc/wireguard/wg0.conf'''
[Interface]
Address = 10.0.0.1/24
PrivateKey =
ListenPort = 51820
[Peer]
PublicKey =
AllowedIPs = 10.0.0.2/32
Endpoint = [YOUR_IPV6_HOME_ADDRESS]:51820
PersistentKeepalive = 25
Local server: '''/etc/wireguard/wg0.conf'''
[Interface]
Address = 10.0.0.2/24
PrivateKey =
ListenPort = 51820
[Peer]
PublicKey =
AllowedIPs = 10.0.0.1/32
Endpoint = :51820
PersistentKeepalive = 25
===== Step 4: Start Tunnel and Make it Persistent =====
sudo wg-quick up wg0
sudo systemctl enable wg-quick@wg0
===== Step 5: Adjust Firewall =====
Using ufw:
sudo ufw allow 51820/udp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
===== Step 6: Configure Nginx as Reverse Proxy =====
File: '''/etc/nginx/sites-available/mond-keks.de'''
server {
server_name domain.com www.domain.com;
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/letsencrypt/live/mond-keks.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mond-keks.de/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://10.0.0.2:80; # WireGuard IP of home server
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
listen [::]:80;
server_name domain.com www.domain.com;
return 301 https://$host$request_uri;
}
===== Step 7: Testing =====
* Browser: https://mond-keks.de
* Check tunnel: wg show
* View logs: tail -f /var/log/nginx/access.log
===== Result =====
Your domain points to the VPS, Nginx terminates HTTPS and forwards requests
through the WireGuard tunnel to your home server. This way, your site stays local
but is globally accessible.