Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →You can host a WireGuard VPN server in Docker by running the LinuxServer.io WireGuard image, persisting its /config directory, creating one peer configuration per client, and making the server’s UDP port reachable from the internet. A running container alone does not guarantee remote access: you may also need to configure the Docker host firewall and forward the UDP port through your router. Before importing a client profile, decide whether it should route all traffic through the VPN or only selected networks.
What you need before starting
- A Linux host running Docker and Docker Compose, with a kernel that supports WireGuard. The LinuxServer.io image guide also discusses loading required modules on the host if they are not already available.
- A host directory for persistent configuration files. The example below uses
/opt/wireguard; choose a path appropriate to your system and make sure the mapped user can write to it. - A reachable public endpoint: an external IP address or domain name, plus a UDP port you can publish and, if the Docker host is behind a router, forward to that host.
- Client devices on which you can import a WireGuard configuration or scan its QR code.
The steps use the LinuxServer.io image, documented at LinuxServer.io’s WireGuard image page. Its project README describes WireGuard as “an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography”; that is the project’s characterization, not an independent performance comparison. LinuxServer.io project README.
Choose what client traffic will use the VPN
Make this decision before distributing client profiles. The image documentation’s default ALLOWEDIPS value, 0.0.0.0/0, ::0/0, routes all IPv4 and IPv6 traffic through the VPN. This is a full tunnel. For split tunneling, narrow ALLOWEDIPS to the networks clients should reach through the server, and include the server’s WireGuard address where appropriate; the documentation gives 10.13.13.1 as an example. Use the actual network ranges in your setup rather than copying that example blindly. LinuxServer.io configuration guidance.
| Choice | Client routing behavior | Useful when |
|---|---|---|
| Full tunnel | All IPv4 and IPv6 traffic is routed through the VPN when connected. | You want the client’s general internet traffic to use the VPN server’s connection. |
| Split tunnel | Only the specified networks use the VPN; other traffic follows the client’s usual route. | You need access to selected home or private networks without sending all client traffic through the VPN. |
Check the generated client profile’s AllowedIPs before importing it. A profile with the full-tunnel default has a different effect from one limited to your LAN or other selected networks.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
Create a Docker Compose deployment
LinuxServer.io recommends Compose for this image. Create a directory for the deployment and save a Compose file there. Replace the example endpoint, user and group IDs, timezone, peer names, and any network values with choices for your host and network.
services:
wireguard:
image: lscr.io/linuxserver/wireguard:latest
container_name: wireguard
cap_add:
- NET_ADMIN
# Optional: use when required modules are not loaded on the host
- SYS_MODULE
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- SERVERURL=your-public-ip-or-domain
- SERVERPORT=51820
- PEERS=phone,laptop
- PEERDNS=auto
- INTERNAL_SUBNET=10.13.13.0
- ALLOWEDIPS=0.0.0.0/0,::0/0
# Optional; example peer names and interval are documented by LinuxServer.io
# - PERSISTENTKEEPALIVE_PEERS=phone,laptop
volumes:
- /opt/wireguard:/config
# Optional: mount when the container needs access to host modules
- /lib/modules:/lib/modules
ports:
- 51820:51820/udp
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
restart: unless-stopped
The values shown are an example based on LinuxServer.io’s documented Compose configuration, not universal requirements. In particular, the sample uses UDP port 51820 and tunnel network 10.13.13.0; adapt them if your network or deployment requires different values. NET_ADMIN is needed by the image to create the WireGuard interface. SYS_MODULE and the /lib/modules mount are optional when the needed modules are already loaded; alternatively, load the modules on the host. LinuxServer.io marks the net.ipv4.conf.all.src_valid_mark=1 sysctl as required for client mode, so do not treat it as a universal server-mode requirement. Some Portainer versions may not correctly apply the capabilities or sysctl this image needs. LinuxServer.io image documentation.
Rank #2
PUID and PGID map the container’s file access to a host user and group to help avoid volume-permission problems. Set them to IDs that make sense for your host. The /config bind mount is important: it keeps generated server and peer files outside the container so they persist across restarts and container replacement.
Set the endpoint and peer values
SERVERURLis the external IP address or domain clients use to reach the server. If your public IP changes, a domain backed by a suitable dynamic-DNS arrangement can provide a stable name; the image documentation supports using an IP or domain.SERVERPORTis the external port advertised to clients. Keep it consistent with the published container port and the router’s forwarding rule, unless you intentionally use a different external port.PEERScreates client profiles. A number creates that many peers; comma-separated names make them easier to identify, such asphone,laptop.PEERDNSselects DNS behavior for clients. Choose a resolver appropriate to the networks you want clients to use.INTERNAL_SUBNETsets the WireGuard tunnel’s internal network. Avoid choosing a range that conflicts with networks clients already use.ALLOWEDIPSsets the traffic routes in the generated client profiles. Use the full-tunnel or split-tunnel choice described above.PERSISTENTKEEPALIVE_PEERSis an optional setting for peers that need keepalives; the documentation’s example interval is 25 seconds when enabled for listed peers. This is a configuration option, not a universal requirement.
Start the container and create client profiles
- From the directory containing your Compose file, run
docker compose up -d. - Check startup output with
docker compose logs -f wireguard. Resolve any image, permission, capability, or module errors shown there before proceeding. - Inspect the host directory you mounted at
/config. LinuxServer.io’s image generates server and peer configuration files there, including client configuration files and QR code images. - Import the configuration for each device using its WireGuard app, or scan that peer’s QR code. Use a distinct peer for each client device so you can identify and manage configurations individually.
- Protect the configuration files and any QR codes. They contain connection credentials for the VPN. If you enable
LOG_CONFS=true, configuration QR codes can also appear in Docker logs; treat access to those logs as sensitive.
Do not publish peer files or QR codes. If you need to change server-mode environment variables later, review LinuxServer.io’s regeneration behavior first: several variables trigger configuration regeneration. The documentation says existing peer keys are retained during normal regeneration, while deleting peer folders changes that behavior. Keep a recoverable copy of /config before making such changes. LinuxServer.io regeneration notes.
Free tools Windows power users keep installed
One-click scans. No signup required.
Allow connections from outside your network
The Compose example publishes UDP port 51820 from the container to the Docker host. Publishing the port does not by itself make the service reachable from the internet. If the host is behind a home router, create an inbound UDP forwarding rule from the router’s external port to the Docker host’s LAN address and the chosen UDP port. Also check that the host firewall allows that traffic. The exact settings depend on your router, host firewall, addressing, and network provider. A router that cannot forward the needed UDP port may need to be replaced or supplemented; new hardware is unnecessary if your current router can do the job. LinuxServer.io port and networking guidance.
For clients connecting from outside, make sure the profile’s endpoint uses the public IP or domain and the correct external UDP port. A private LAN address works only for clients that can reach that LAN directly.
Rank #4
Test remote access and handle connections from home
Test from a network outside the server’s LAN, such as a phone using mobile data. Activate the peer and check whether it can reach the networks or internet traffic you intended to route. A successful container start is not proof of public reachability: the path also depends on port publishing, host firewall rules, router forwarding, public addressing, and any restrictions imposed by the network provider.
When a client is back on the same home LAN, using the public endpoint may fail even though remote access works. Some routers do not send a connection from the LAN to the public WAN address back to the LAN server, a behavior commonly called hairpin NAT or NAT reflection. Depending on your network, use router NAT reflection or split-horizon DNS so the same domain resolves to an internal address at home and a public address away from home. LinuxServer.io local-access notes.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Troubleshoot common setup failures
- The container exits or the interface is not created: inspect
docker compose logs wireguard. Check that Docker has appliedNET_ADMIN, and confirm the host kernel has WireGuard and required iptables support. If needed, load the relevant modules on the host or use the optional module access documented for the image. - The client cannot connect from outside: confirm the Compose port mapping is UDP, the router forwards the selected external UDP port to the Docker host, and the host firewall allows it. Verify the client endpoint is the public address or domain and uses the correct port.
- The tunnel connects but the client cannot reach the intended destination: inspect the profile’s
AllowedIPsand confirm it includes the network you want to route. For split tunneling, include only the selected destinations; for full tunneling, the profile must include the all-traffic routes. - The server is reachable remotely but not from the home LAN using its public name: check whether the router supports NAT reflection. If not, split-horizon DNS or a LAN-specific endpoint may fit your network better.
- Changes do not appear in peer files: check whether the changed environment variable triggers configuration regeneration and review the image’s rules before removing or altering peer folders. Back up
/configfirst.
LinuxServer.io documents the image’s configuration and networking behavior, but your actual router, firewall, ISP, and client setup determine whether a particular deployment is reachable.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

