Self Hosted VPN Guide: WireGuard + Docker on a VPS
A self hosted vpn gives you total control over your encrypted traffic. Instead of trusting a commercial provider with your data, you route your connections through a server you own and operate.
If your goal is to spin up a private tunnel in minutes, the modern standard is combining WireGuard (protocol) with wg-easy (management UI) running in Docker. This approach removes the complexity of manual key generation while maintaining the speed and security WireGuard is known for.
Secure data collection with LycheeIP
What problem does a self hosted vpn actually solve?
Before deploying infrastructure, clarify your use case. A self-hosted setup typically solves three specific engineering problems:
- Secure Remote Access: You need to reach services running in your home lab or private cloud (like a database or dashboard) without exposing them to the public internet.
- Trusted Egress: You are on untrusted public Wi-Fi (coffee shop, hotel) and want to encrypt traffic before it leaves your device.
- Static IP Control: You need a consistent static IP address for allowing access to specific firewalls or APIs.
Note: A self hosted vpn does not provide anonymity from your VPS provider. The hosting company (e.g., DigitalOcean, Hetzner, AWS) can still see connection metadata.
Why use WireGuard and wg-easy for this stack?
WireGuard has largely replaced OpenVPN for new deployments because it is leaner, faster, and easier to audit. However, native WireGuard requires managing config files and public/private keys via the command line.
wg-easy bridges this gap. It is a Docker container that bundles:
- WireGuard implementation.
- A clean Web UI for creating/revoking users.
- QR code generation for mobile clients.
- Usage statistics.
This combination allows you to treat your VPN like a product rather than a sysadmin chore.
Step 1: Choosing the right VPS specs and location
You do not need an expensive server. WireGuard is extremely CPU efficient.
- CPU/RAM: 1 vCPU and 512MB - 1GB RAM is sufficient for personal use (1–5 concurrent users).
- Bandwidth: This is the bottleneck. Ensure your provider offers at least 1TB of monthly transfer and a port speed of 1Gbps.
- Virtualization: KVM-based VPS instances are preferred over OpenVZ, as KVM handles kernel modules (required for WireGuard) more reliably.
Location Matters
Latency is determined by physics. If you are in New York, a VPS in London adds unnecessary lag. Pick a data center geographically closest to where you will physically be most often.
Step 2: Deploying wg-easy with Docker Compose
Prerequisites: A Linux VPS (Ubuntu 22.04 LTS recommended) with Docker and Docker Compose installed.
Critical network settings (IP Forwarding)
Before running the container, the host OS must allow IP forwarding. Without this, your server receives the traffic but drops it instead of passing it to the internet.
Run this command on your host:
Bash
sysctl net.ipv4.ip_forward=1
To make it permanent, add net.ipv4.ip_forward=1 to your /etc/sysctl.conf file.
The docker-compose.yml configuration
Create a docker-compose.yml file. Replace the WG_HOST with your VPS public IP and set a strong password.
YAML
version: "3.8"
services:
wg-easy:
image: ghcr.io/wg-easy/wg-easy
container_name: wg-easy
restart: unless-stopped
environment:
# Replace with your VPS Public IP or Domain
- WG_HOST=203.0.113.1
# The Web UI password (make this strong)
- PASSWORD=YourSecurePassword123!
# Optional: default DNS for clients (Cloudflare or Google)
- WG_DEFAULT_DNS=1.1.1.1
volumes:
- ./wg-easy-data:/etc/wireguard
ports:
- "51820:51820/udp" # WireGuard Tunnel
- "51821:51821/tcp" # Web UI
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.ip_forward=1
- net.ipv6.conf.all.forwarding=1
Run the stack:
Bash
docker compose up -d
You can now access the admin UI at http://YOUR_VPS_IP:51821.
Step 3: Client configuration and split tunneling
In the Web UI, click "New Client," name it (e.g., "iPhone"), and you will get a QR code and a download link for the .conf file.
- Mobile: Install the WireGuard app and scan the QR code.
- Desktop: Install the WireGuard client and import the .conf file.
Full Tunnel vs Split Tunnel Decision Matrix
The most important setting in your config is AllowedIPs. This determines which traffic goes through the VPN.
| Configuration | AllowedIPs Setting | Best For |
| Full Tunnel | 0.0.0.0/0, ::/0 | Public Wi-Fi security. Routes everything through the VPN. |
| Split Tunnel | 10.8.0.0/24, 192.168.1.0/24 | Accessing home labs/private servers while keeping normal browsing on your local ISP. |
| Hybrid | 0.0.0.0/0 (with exclusions) | Advanced users who want to exclude high-bandwidth apps (like Steam/Netflix) from the tunnel. |
Secure data collection with LycheeIP
Security: How to harden your VPN server
Running a self hosted vpn shifts the security responsibility to you. Do not leave your server vulnerable.
- Secure the Web UI: The default setup exposes the admin panel on port 51821 over HTTP. Do not leave this open.
- Best Practice: Use a reverse proxy (like Nginx or Traefik) with Let's Encrypt SSL.
- Alternative: Block port 51821 on the firewall and access it only via SSH tunnel (ssh -L 51821:localhost:51821 user@host).
- Firewall Rules: Your VPS firewall (UFW) needs to be strict.
- Allow UDP 51820 (VPN traffic).
- Allow TCP 22 (SSH access).
- Deny everything else (unless you are serving other apps).
- Automatic Updates: Enable unattended-upgrades on Ubuntu to ensure security patches are applied automatically.
Troubleshooting common WireGuard failures
If your connection isn't working, check these common culprits.
- The "Handshake" Failure: If the client shows "sending handshake initiation" but never receives a response, the UDP packets are being blocked. Check your VPS firewall and your cloud provider’s security groups to ensure UDP port 51820 is open.
- Connected but no Internet: This is usually a routing issue. Verify net.ipv4.ip_forward=1 is active on the host. Also, check that your Docker container has NET_ADMIN capabilities.
- DNS Leaks: If you can ping IP addresses (like 8.8.8.8) but cannot load websites, your DNS config is failing. Ensure WG_DEFAULT_DNS is set to a reliable resolver like 1.1.1.1 or 8.8.8.8.
Comparison: Self-hosted vs Tailscale vs Cloudflare
Is self-hosting always the right choice? Not always.
| Feature | Self Hosted (WireGuard) | Tailscale / ZeroTier | Cloudflare WARP/Tunnel |
| Setup Difficulty | Medium (requires Linux knowledge) | Very Low | Low |
| Performance | High (Direct p2p or via VPS) | High (Mesh networking) | Variable (via Cloudflare edge) |
| Anonymity | High (You own the data path) | Medium (Control plane sees metadata) | Low (Decrypted at edge) |
| Cost | VPS Cost ($4-6/mo) | Free for personal use | Free basic tier |
| Best For | Privacy & total control | Connecting many devices easily | Accessing internal apps |
Limitations: When a VPN is the wrong tool (Data Ops)
While a self hosted vpn is excellent for security and access, it is poor infrastructure for data collection, scraping, or multi-account management.
- Single Point of Failure: Your VPN provides one IP address. If that IP gets flagged or banned by a target site, your access is gone.
- Lack of Rotation: You cannot rotate IPs on a standard VPN setup without buying multiple VPS instances, which becomes expensive and hard to manage.
- Digital Fingerprinting: Commercial VPN datacenter IPs are easily detected by sophisticated anti-fraud systems.
How LycheeIP fits
For data-intensive tasks, dedicated proxy infrastructure is required. LycheeIP provides the resources that a single VPS cannot:
- Residential Pools: Millions of ethical IPs that look like real user devices, not datacenter servers.
- Automatic Rotation: Switch IPs automatically per request to avoid rate limits.
- Developer API: Integrate IP management directly into your scraping code, rather than managing network interfaces.
If your goal is secure access, stick to the self hosted vpn. If your goal is reliable data extraction or managing multiple accounts, look at proxy solutions.
Secure data collection with LycheeIP
Frequently Asked Questions (FAQs)
1. Is a self hosted vpn free?
The software (WireGuard/Docker) is free, but you must pay for the VPS hosting it. This typically costs between $4 and $6 USD per month.
2. Can I run this on a Raspberry Pi at home?
Yes. You can use the exact same Docker Compose setup. However, you will need to configure "Port Forwarding" on your home router to send traffic from the internet to your Raspberry Pi.
3. Why is WireGuard faster than OpenVPN?
WireGuard uses modern cryptography and runs inside the Linux kernel, which reduces the processing overhead compared to OpenVPN, which runs in user space.
4. Does this setup hide my browsing from my ISP?
Yes. Your ISP will only see encrypted UDP traffic going to your VPS IP address. They cannot see which websites you are visiting.
5. What is the difference between a VPN and a Proxy?
A VPN encrypts your entire device's network traffic at the operating system level. A proxy typically handles traffic for a specific application (like a browser or scraper) and does not always provide encryption.
6. Can I use this for Netflix or streaming?
Maybe. Streaming services often block IP addresses belonging to known VPS providers (DigitalOcean, Linode, etc.). A self hosted vpn is not the most reliable method for unblocking geo-restricted content.