====== 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.