What You Will Need
| Requirement | Details |
|---|---|
| RamNode VPS | KVM VPS with 1+ GB RAM, Ubuntu 22.04 or 24.04 LTS |
| Domain name (optional) | For HTTPS access to the web UI (e.g., vpn.yourdomain.com) |
| SSH access | Root or sudo-enabled user on your VPS |
| Firewall ports | UDP 51820 (WireGuard), TCP 443 (HTTPS) or TCP 51821 (HTTP) |
Why WG-Easy on RamNode?
- WireGuard kernel-level performance on RamNode KVM instances with full root access
- Web UI for effortless client management, QR codes, and real-time connection stats
- Minimal resource footprint — runs comfortably on RamNode's $5/month plan (1 vCPU, 1 GB RAM)
- Docker Compose deployment for reproducible, portable infrastructure
- IPv4 and IPv6 dual-stack support with v15's complete rewrite
Prepare Your RamNode VPS
sudo apt update && sudo apt upgrade -yVerify Kernel WireGuard Support
All modern Linux kernels (5.6+) include WireGuard natively. Verify your kernel version:
uname -rInstall Docker and Docker Compose
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $(whoami)
newgrp docker
# Verify installation
docker --version
docker compose versionConfigure the Firewall
sudo ufw allow 22/tcp # SSH
sudo ufw allow 51820/udp # WireGuard VPN tunnel
sudo ufw allow 443/tcp # HTTPS for web UI (if using Caddy)
sudo ufw allow 51821/tcp # HTTP web UI (if not using reverse proxy)
sudo ufw enable
sudo ufw statusTip: If you plan to use Caddy as a reverse proxy (recommended), you only need ports 22, 51820/udp, and 443/tcp. You can skip opening port 51821 since Caddy will handle HTTPS termination.
Generate a Password Hash
WG-Easy v15+ requires a bcrypt-hashed password for the admin UI. Generate one using the built-in utility:
docker run --rm -it ghcr.io/wg-easy/wg-easy wgpw 'YourSecurePassword'Copy the bcrypt hash for use in the next step. When placing the hash in your Docker Compose file, you must escape every dollar sign ($) by doubling it ($). Example: $2a$12$abc... becomes $2a$12$abc...
Deploy WG-Easy with Docker Compose
mkdir -p ~/wg-easy && cd ~/wg-easyvolumes:
etc_wireguard:
services:
wg-easy:
image: ghcr.io/wg-easy/wg-easy
container_name: wg-easy
environment:
- LANG=en
- WG_HOST=YOUR_SERVER_IP_OR_DOMAIN
- PASSWORD_HASH=YOUR_BCRYPT_HASH_HERE
- PORT=51821
- WG_PORT=51820
volumes:
- etc_wireguard:/etc/wireguard
ports:
- "51820:51820/udp"
- "51821:51821/tcp"
restart: unless-stopped
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1Key Configuration Values
| Variable | Description |
|---|---|
| WG_HOST | Your VPS public IP or domain name (e.g., vpn.example.com) |
| PASSWORD_HASH | Bcrypt hash from Step 4 (remember to escape $ as $) |
| PORT | Web UI listening port inside the container (default: 51821) |
| WG_PORT | WireGuard UDP port for VPN traffic (default: 51820) |
| LANG | Web UI language (en, de, fr, es, zh, and many more) |
cd ~/wg-easy
docker compose up -d
# Verify the container is running
docker compose ps
docker compose logs -f wg-easySecure with Caddy Reverse Proxy (Recommended)
Running the WG-Easy web UI over plain HTTP is insecure. Caddy provides automatic HTTPS with Let's Encrypt certificates. This step requires a domain name pointed at your VPS.
volumes:
etc_wireguard:
caddy_data:
services:
wg-easy:
image: ghcr.io/wg-easy/wg-easy
container_name: wg-easy
environment:
- LANG=en
- WG_HOST=vpn.yourdomain.com
- PASSWORD_HASH=YOUR_BCRYPT_HASH_HERE
- PORT=51821
- WG_PORT=51820
volumes:
- etc_wireguard:/etc/wireguard
ports:
- "51820:51820/udp"
restart: unless-stopped
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1
caddy:
image: caddy:2
container_name: caddy
ports:
- "443:443"
- "80:80"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
restart: unless-stoppedvpn.yourdomain.com {
reverse_proxy wg-easy:51821
}Note: Replace vpn.yourdomain.com with your actual domain. Ensure your DNS A record points to your RamNode VPS IP address before starting the stack. Caddy will automatically obtain and renew TLS certificates.
docker compose down
docker compose up -dYour WG-Easy admin panel is now accessible at https://vpn.yourdomain.com with a valid TLS certificate.
Connect Your First VPN Client
Create a Client in the Web UI
- Open the WG-Easy admin panel in your browser
- Log in with the admin password you set in Step 4
- Click "New Client" and enter a descriptive name (e.g., "Laptop", "Phone")
- Click "Create" to generate the client configuration
Install WireGuard on Your Device
| Platform | Installation |
|---|---|
| Windows | Download from wireguard.com/install → Import tunnel → Select .conf file |
| macOS | Install from App Store → Import tunnel from file |
| Linux | sudo apt install wireguard → wg-quick up ./client.conf |
| iOS / Android | Install WireGuard from App Store / Play Store → Scan QR code |
Verify the Connection
curl ifconfig.meThe returned IP should match your RamNode VPS public IP address.
Advanced Configuration
Optional Environment Variables
| Variable | Description | Default |
|---|---|---|
| WG_DEFAULT_DNS | DNS server for clients | 1.1.1.1 |
| WG_DEFAULT_ADDRESS | Client IP range | 10.8.0.x |
| WG_ALLOWED_IPS | Allowed IPs for clients | 0.0.0.0/0, ::/0 |
| WG_PERSISTENT_KEEPALIVE | Keepalive interval (seconds) | 0 (disabled) |
| WG_MTU | MTU for WireGuard interface | null (auto) |
| UI_TRAFFIC_STATS | Enable traffic charts in UI | false |
Backup & Maintenance
Troubleshooting
| Issue | Solution |
|---|---|
| Web UI not loading | Verify firewall allows TCP 51821 (or 443 if using Caddy). Check container logs for errors. |
| VPN connects but no internet | Ensure net.ipv4.ip_forward=1 is set. Check that the host firewall isn't blocking forwarded traffic. |
| Password hash not accepted | Regenerate with the wgpw command. Ensure all $ are escaped as $ in docker-compose.yml. |
| QR code won't scan | Ensure WG_HOST is set to your public IP or domain, not a private/internal address. |
| Caddy certificate fails | Verify DNS A record resolves to your VPS IP. Ports 80 and 443 must be open for the ACME challenge. |
| Container keeps restarting | Check logs with docker compose logs. Common cause: invalid PASSWORD_HASH format or missing capabilities. |
WG-Easy Deployed Successfully!
Your self-hosted WireGuard VPN server with web admin UI is now running. Create clients, share QR codes, and enjoy kernel-level VPN performance on your RamNode VPS.
