# How to Deploy a High-Speed WireGuard VPN Server in Docker in Under 15 Minutes

> Markdown version of an Informer Tech article. Canonical HTML page: https://www.informertech.com/post/deploy-wireguard-vpn-docker
> Source: Informer Tech, https://www.informertech.com/

- **Canonical URL:** https://www.informertech.com/post/deploy-wireguard-vpn-docker
- **Publisher:** Informer Tech (https://www.informertech.com/)
- **Category:** VPNs, Installation Guides
- **Author:** Tomáš Král
- **Published:** 2026-10-29
- **Description:** Deploy a WireGuard VPN server in Docker in 15 minutes using Docker Compose. Covers Ubuntu setup, peer routing, firewall rules, and speed testing.

---

A WireGuard VPN server in Docker provides a private route through a server you control. The setup below connects one device and verifies its traffic path.

Allow roughly 15 minutes once Docker, SSH access, and public connectivity are ready. Server provisioning and network troubleshooting can take additional time. Treat high speed as something to measure rather than a guaranteed result.

## Before deploying your WireGuard VPN server in Docker

Start with an Ubuntu 24.04 LTS server running Docker Engine and its Compose plugin. Follow [Docker’s installation instructions](https://docs.docker.com/engine/install/ubuntu/?utm_source=prolaunch.net) if either component is missing.

Use a public IPv4 address or a hostname pointing to it. Allow inbound UDP port <code>51820</code> through the provider’s firewall. For a home server, forward that UDP port to its LAN address.

The host needs working WireGuard and iptables kernel support. Confirm compatibility before deployment because Docker cannot supply a missing host kernel feature.

## Deploy WireGuard with Docker Compose

The [LinuxServer.io image](https://docs.linuxserver.io/images/docker-wireguard/?utm_source=prolaunch.net) generates server and client configurations from environment variables.

### Create the Compose configuration

Prepare a private configuration directory using your normal SSH account:

<pre class="ql-syntax" spellcheck="false">mkdir -p ~/wireguard/config
cd ~/wireguard
chmod 700 config
id -u
id -g
</pre>
Create <code>compose.yaml</code> with the configuration below. Replace <code>YOUR_PUBLIC_IP</code> and substitute the displayed user and group IDs for <code>1000</code>.

<pre class="ql-syntax" spellcheck="false">services:
  wireguard:
    image: lscr.io/linuxserver/wireguard:latest
    container_name: wireguard
    cap_add:
      - NET_ADMIN
    environment:
      PUID: "1000"PGID: "1000"TZ: Etc/UTC
      SERVERURL: YOUR_PUBLIC_IP
      SERVERPORT: "51820"PEERS: "1"PEERDNS: "1.1.1.1"ALLOWEDIPS: "0.0.0.0/0"LOG_CONFS: "false"volumes:
      - ./config:/config
    ports:
      - "51820:51820/udp"sysctls:
      net.ipv4.ip_forward: "1"
      net.ipv4.conf.all.src_valid_mark: "1"restart: unless-stopped
</pre>
<code>PEERS</code> creates one device profile, while <code>PEERDNS</code> selects its DNS resolver. Setting <code>LOG_CONFS=false</code> keeps configuration QR codes out of container logs.

Preload required kernel modules on the host if necessary. The image documents optional <code>SYS_MODULE</code> and <code>/lib/modules</code> access for loading missing modules from the container.

### Start the container and check network access

Start the service and inspect its status and logs:

<pre class="ql-syntax" spellcheck="false">sudo docker compose up -d
sudo docker compose ps
sudo docker compose logs wireguard
</pre>
A running container still needs a reachable public endpoint. Check the provider firewall and any router forwarding rules.

[Docker’s firewall documentation](https://docs.docker.com/engine/network/packet-filtering-firewalls/?utm_source=prolaunch.net) explains that published ports can bypass UFW rules. Don’t assume UFW alone controls the container’s network exposure.

## Connect a device and choose VPN routing

Each participating device, called a peer, needs its own profile. Transfer <code>config/peer1/peer1.conf</code> securely to the device and import it into an [official WireGuard client](https://www.wireguard.com/install/?utm_source=prolaunch.net).

This configuration routes all IPv4 destinations through the VPN. Split tunneling routes only selected destinations, determined by <code>AllowedIPs</code>. The [wg-quick manual](https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8?utm_source=prolaunch.net) explains these routing rules.

IPv6 needs separate handling because <code>0.0.0.0/0</code> covers IPv4 only. Block untunneled IPv6 on the client until dual-stack routing is configured and tested. On Windows, retain the client’s full-tunnel blocking behavior described in its [network documentation](https://git.zx2c4.com/wireguard-windows/about/docs/netquirk.md?utm_source=prolaunch.net).

## Verify your WireGuard Docker VPN and troubleshoot performance

Successful deployment means traffic follows the intended route, beyond simply displaying an active connection.

### Confirm the tunnel carries traffic

Connect from another network, such as mobile data, then browse a website. Inspect the server using WireGuard’s [status command](https://www.wireguard.com/quickstart/?utm_source=prolaunch.net):

<pre class="ql-syntax" spellcheck="false">sudo docker exec wireguard wg show
</pre>
Look for a recent handshake and increasing transfer counters. Confirm the client’s public IPv4 matches the server’s address. Check DNS resolution and ensure IPv6 cannot bypass the tunnel.

### Measure speed and isolate failures

Compare throughput with and without the tunnel using the same test endpoint. For controlled measurements, [iperf3](https://software.es.net/iperf/invoking.html?utm_source=prolaunch.net) provides client/server testing and reverse-direction tests through <code>-R</code>.

Troubleshoot according to the symptom:

- Without a handshake, check the endpoint, UDP reachability, and keys.
- With a handshake but no browsing, check forwarding, routing, and DNS.
- With stalled transfers, investigate MTU, the maximum packet size.

Keep automatic MTU sizing initially, as recommended by the wg-quick documentation. Change it when testing identifies a packet-size problem.

## Secure and maintain the WireGuard VPN server

Treat configuration files as credentials because they contain private keys. Restrict access and keep an encrypted backup of the configuration directory.

Create separate profiles for additional devices by increasing <code>PEERS</code> and recreating the container. Changing configuration variables preserves existing keys; it does not replace compromised credentials. Follow the image’s regeneration instructions when rotating keys.

After backing up, [update the image and recreate the service](https://docs.linuxserver.io/general/updating-our-containers/?utm_source=prolaunch.net):

<pre class="ql-syntax" spellcheck="false">sudo docker compose pull
sudo docker compose up -d
</pre>
The bind mount preserves configuration across container recreation. Repeat the connection checks after each update before relying on the tunnel.

## Confirm the deployment before relying on it

A WireGuard VPN server in Docker is ready when handshakes, routing, and DNS work as intended. Confirm IPv6 handling and measure performance before relying on it. Protect the backup and issue a separate profile for each additional device.

## FAQ

### Does WireGuard in Docker need privileged mode?

The example uses <code>NET_ADMIN</code> rather than unrestricted privileged mode. Module loading may require the optional access documented by LinuxServer.io. [LinuxServer.io](https://docs.linuxserver.io/images/docker-wireguard/?utm_source=prolaunch.net)

### Can I route only selected traffic through WireGuard?

Set <code>AllowedIPs</code> to the required destination ranges instead of the default route. Include the tunnel server address when needed. [git.zx2c4.com](https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8?utm_source=prolaunch.net)

### Why does WireGuard connect without providing internet access?

A handshake confirms peer communication but doesn’t prove correct forwarding or DNS. Check both before changing keys or reinstalling the container. [WireGuard](https://www.wireguard.com/quickstart/?utm_source=prolaunch.net)

### Will this setup guarantee gigabit speeds?

Deployment alone does not establish any particular throughput. WireGuard labels its published [benchmarks outdated](https://www.wireguard.com/performance/?utm_source=prolaunch.net), making actual connection measurements more useful. [WireGuard](https://www.wireguard.com/performance/?utm_source=prolaunch.net)
