Creating a WireGuard VPN Server for Secure Remote Access to Your Homelab

Creating a WireGuard VPN Server for Secure Remote Access to Your Homelab

I've tried several VPN solutions for accessing my homelab remotely—OpenVPN, Tailscale, traditional reverse proxies—but WireGuard strikes the best balance between security, speed, and simplicity. Unlike OpenVPN with its 16,000 lines of code, WireGuard runs on just 4,000 lines of code in the kernel, making it auditable and blazing fast. When I needed a self-hosted solution I could run on a cheap VPS (you can grab one for around $40/year from providers like RackNerd), WireGuard became my go-to.

In this guide, I'll walk you through setting up a WireGuard server in Docker, generating peer configurations for your devices, and securing it properly. This approach works on any Linux server—whether that's a homelab machine or a public VPS.

Why WireGuard Over Other VPN Options?

Before we dive into the setup, let me explain why I prefer WireGuard for homelab access. First, it's modern—designed from scratch in 2015, unlike OpenVPN which dates to 2002. Second, the cryptography is hardened with WireGuard using only proven algorithms (ChaCha20, Poly1305, Curve25519). Third, it's fast—I measured throughput improvements of 3-4x over OpenVPN on the same hardware.

WireGuard also handles key rotation automatically and uses a simpler configuration model. Each peer (phone, laptop, server) gets a keypair, and the server maintains a simple list of allowed IPs. There's no complex certificate management or session negotiation—just cryptographic identities.

The tradeoff? WireGuard is less "invisible" to network monitoring since all traffic uses the same UDP port. But for homelab use, that's not a concern.

Prerequisites and Planning

You'll need:

For this guide, I'm assuming you'll run WireGuard on a VPS. A basic VPS from RackNerd or similar providers (typically $3-4/month) is more than sufficient. I prefer running WireGuard on a separate public server rather than exposing my homelab's IP directly to the internet.

The network topology will look like this: Your homelab runs behind NAT → WireGuard server sits on a VPS with a public IP → Your phone/laptop connects to the WireGuard server → Traffic is routed back to your homelab over the tunnel.

Setting Up WireGuard with Docker

I use the linuxserver/wireguard Docker image, which handles key generation and configuration automatically. Here's my Docker Compose setup:

version: '3.8'
services:
  wireguard:
    image: linuxserver/wireguard:latest
    container_name: wireguard
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/Denver
      - SERVERURL=your-server-domain.com
      - SERVERPORT=51820
      - PEERS=phone,laptop,tablet
      - PEERDNS=8.8.8.8,8.8.4.4
      - ALLOWEDIPS=10.13.13.0/24
      - INTERNAL_SUBNET=10.13.13.0/24
      - LOG_CONFS=true
    ports:
      - "51820:51820/udp"
    volumes:
      - /opt/wireguard/config:/config
      - /lib/modules:/lib/modules:ro
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    restart: unless-stopped

This configuration creates a WireGuard server with three peer profiles (phone, laptop, tablet). Let me break down the key environment variables:

Start the container:

docker-compose up -d wireguard

After startup, check the logs to confirm the keys were generated:

docker logs wireguard | grep -i "keys generated"

Accessing Your Peer Configurations

Once the container is running, WireGuard has created configuration files for each peer in /opt/wireguard/config/peer_*/. Each folder contains:

To retrieve a peer config for your phone:

cat /opt/wireguard/config/peer_phone/wg0.png

This PNG is a QR code you can scan directly in the WireGuard mobile app. For laptop configurations, you can copy the wg0.conf file:

cat /opt/wireguard/config/peer_laptop/wg0.conf

The config will look something like:

[Interface]
Address = 10.13.13.2/32
DNS = 8.8.8.8,8.8.4.4
PrivateKey = XXXX...
Watch out: These private keys are sensitive. Never commit them to git or share them. If a peer is compromised, regenerate its keys and remove the peer from your server configuration.

Routing Traffic Back to Your Homelab

Now here's the critical part: your WireGuard clients are connected to the VPN, but they can't reach your homelab yet. You need to configure routing.

If your homelab is on a private subnet (e.g., 192.168.1.0/24) and you want VPN clients to access it, you have two options:

  1. Route everything through the VPN: Set AllowedIPs = 0.0.0.0/0 in the client config (sends all traffic through the tunnel)
  2. Route only to your homelab: Set AllowedIPs = 10.13.13.0/24, 192.168.1.0/24 (only homelab traffic goes through the tunnel)

I prefer option 2 for performance. Edit the server config to include your homelab subnet:

docker exec wireguard wg set wg0 allowed-ips 10.13.13.1/32 192.168.1.0/24

But this is temporary. To make it permanent, you'll need to modify the peers. The easier approach is to update the Docker Compose environment variable and regenerate. Alternatively, manually edit /opt/wireguard/config/wg_confs/wg0.conf and restart:

docker-compose down wireguard
# Edit the config file to add your homelab subnet
docker-compose up -d wireguard

On your homelab machine (or router), you also need to add a route back to the WireGuard subnet via your VPS gateway. If your homelab is behind a router, add this route to the router's routing table pointing to your homelab's gateway IP.

Connecting Your Devices

On iOS/Android: Download the WireGuard app from your app store, then tap the "+" button and scan the QR code from your peer config. That's it—no other configuration needed.

On Linux/Mac: Download the peer's wg0.conf file and use:

sudo wg-quick up /path/to/wg0.conf

On Windows: Download the WireGuard installer, then import the .conf file directly from the GUI.

Test connectivity by pinging a machine on your homelab:

ping 192.168.1.100

Hardening Your WireGuard Setup

WireGuard is secure by design, but a few operational practices matter:

Tip: Set up a cron job to regularly back up your WireGuard config directory. If your VPS is compromised, you'll want to quickly regenerate all keys from a backup and redeploy.

Common Issues and Troubleshooting

If clients can't connect, verify:

If you can connect to WireGuard but can't reach your homelab, check routing:

Next Steps

Once WireGuard is running reliably, consider:

WireGuard has been rock-solid in my homelab for two years now. I've never had a leak or unexpected disconnect. If you're currently using a reverse proxy or Tailscale for remote access, WireGuard gives you more control and lower overhead—especially if you're paying for a VPS anyway. The setup is straightforward, and the security is modern.

Discussion