← BACK TO SITE
← BLOG
// ADMIN 2026-03-26

Tutorial: Host a Local Website via VPS with WireGuard and Nginx

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


<code>

  +-------------------+

  |  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)  |

  +-------------------+

</code>



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

<code>

sudo apt update

sudo apt install wireguard

</code>


===== Step 2: Generate Keys =====

<code bash>

wg genkey | tee vps_private.key | wg pubkey > vps_public.key

wg genkey | tee local_private.key | wg pubkey > local_public.key

</code>


===== Step 3: Create Configuration =====

VPS: '''/etc/wireguard/wg0.conf'''

<code ini>

[Interface]

Address = 10.0.0.1/24

PrivateKey = <VPS-Private-Key>

ListenPort = 51820


[Peer]

PublicKey = <Local-Public-Key>

AllowedIPs = 10.0.0.2/32

Endpoint = [YOUR_IPV6_HOME_ADDRESS]:51820

PersistentKeepalive = 25

</code>


Local server: '''/etc/wireguard/wg0.conf'''

<code ini>

[Interface]

Address = 10.0.0.2/24

PrivateKey = <Local-Private-Key>

ListenPort = 51820


[Peer]

PublicKey = <VPS-Public-Key>

AllowedIPs = 10.0.0.1/32

Endpoint = <VPS-IP>:51820

PersistentKeepalive = 25

</code>


===== Step 4: Start Tunnel and Make it Persistent =====

<code>

sudo wg-quick up wg0

sudo systemctl enable wg-quick@wg0

</code>


===== Step 5: Adjust Firewall =====

Using ufw:

<code>

sudo ufw allow 51820/udp

sudo ufw allow 80/tcp

sudo ufw allow 443/tcp

</code>


===== Step 6: Configure Nginx as Reverse Proxy =====

File: '''/etc/nginx/sites-available/mond-keks.de'''

<code nginx>

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;

}

</code>


===== Step 7: Testing =====

 * Browser: https://mond-keks.de

 * Check tunnel: <code>wg show</code>

 * View logs: <code>tail -f /var/log/nginx/access.log</code>


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