A platform-neutral Docker guide to using Gluetun as the Surfshark VPN gateway for selected applications on home servers, NAS systems and Linux hosts.
Gluetun turns Surfshark into a reusable Docker VPN gateway
Gluetun supports Surfshark directly and can establish either OpenVPN or WireGuard connections. A common Docker design is to run Gluetun as the network owner and attach one or more application containers to its network namespace. Those applications then share the Surfshark public IP, DNS path and firewall boundary. This is useful on Unraid, Synology, UGREEN NAS, Linux home servers and other Docker-capable hosts when only selected applications should use the commercial VPN.
What are you trying to protect?
Choose the routing goal first. The best Surfshark architecture changes depending on whether the VPN belongs to one container, an application group, the whole server or remote access.
What Gluetun is and why Surfshark fits it well
Gluetun is a Docker VPN client designed to act as a network gateway. It supports a range of commercial providers and includes a native Surfshark integration. Instead of installing a VPN client separately inside every application container, Gluetun creates the encrypted tunnel and the application containers share its network stack. This gives you a single place to configure the provider, select a location, inspect VPN logs and control the firewall.
Surfshark is a good match because it supports manual WireGuard and OpenVPN connections. WireGuard is usually the better starting point for a modern Docker host because it is efficient and Gluetun has native Surfshark WireGuard support. OpenVPN remains useful as a fallback or for environments where its TCP option solves a connectivity problem that UDP-based WireGuard cannot.
Generate Surfshark WireGuard material before writing Compose
Open the Surfshark account dashboard, go to VPN, Manual setup, choose WireGuard and generate or register a key pair. If Surfshark generates the pair, copy the private key and store it securely because the account flow does not simply reveal it again on demand. Choose a server location and download the configuration file. Gluetun uses the private key and the interface Address value from that file for its native Surfshark WireGuard setup.
Keep the original configuration file as a reference, but do not mount it blindly when using the native provider variables. The Gluetun Surfshark integration expects specific environment values. That makes the setup easier to audit than a pile of custom WireGuard directives, and it lets Gluetun manage the provider server list and location filters.
Use the native Surfshark provider variables
A minimal WireGuard configuration needs VPN_SERVICE_PROVIDER=surfshark, VPN_TYPE=wireguard, WIREGUARD_PRIVATE_KEY and WIREGUARD_ADDRESSES. Add a location filter such as SERVER_COUNTRIES when you want Gluetun to choose a server within a region. Gluetun also supports narrower filters for regions, cities and hostnames. Avoid a single hard-coded hostname unless the application genuinely requires it because provider inventories can change.
For OpenVPN, switch VPN_TYPE to openvpn and provide the Surfshark manual setup username and password. Those credentials are separate from the normal Surfshark account login. This distinction matters because using the account email and password is a common cause of authentication errors in manual OpenVPN deployments.
A clean Docker Compose pattern
The common Compose design is to define Gluetun first, grant NET_ADMIN, expose /dev/net/tun, and provide the Surfshark environment variables. A dependent application in the same Compose file can then use network_mode: service:gluetun. Gluetun documentation says that this makes the second container use the Gluetun network stack. The child container does not need its own VPN settings and does not need a separate default route.
services:
gluetun:
image: qmcgaw/gluetun
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
environment:
- VPN_SERVICE_PROVIDER=surfshark
- VPN_TYPE=wireguard
- WIREGUARD_PRIVATE_KEY=YOUR_PRIVATE_KEY
- WIREGUARD_ADDRESSES=YOUR_SURFSHARK_ADDRESS
- SERVER_COUNTRIES=Netherlands
ports:
- 8080:8080
app:
image: your-image
network_mode: service:gluetun
Treat the snippet as an architecture template, not a secret store. Use your platform secret-management method where possible and never publish a real private key. Also confirm the child application actually listens on the port you map through Gluetun.
Port mapping moves to the Gluetun service
Because the child application shares Gluetun networking, Gluetun owns the host-facing port mappings. The current Gluetun port-mapping documentation gives the same rule: if a connected container listens on port 9000, publish 9000 on the Gluetun container. The child application no longer exposes that port independently to the host network. This is why a container can appear healthy but its WebUI disappears after moving behind Gluetun.
For multiple applications, keep a port inventory. Two containers cannot casually claim the same listening port inside one shared network namespace. Change an application internal port when supported or design separate Gluetun instances when the stacks cannot coexist cleanly. One gateway is convenient, but it should not become a port-collision puzzle.
Allow LAN access with precision
Gluetun blocks traffic according to its firewall policy, which is a major reason to use it. If the protected application must reach a NAS, indexer, database or other LAN service, configure FIREWALL_OUTBOUND_SUBNETS with the required local network. Use the smallest useful CIDR or host route. The current Gluetun documentation warns that an outbound subnet must not overlap the WireGuard tunnel range because overlapping routes can cause VPN traffic to leave by the wrong path.
Do not disable the firewall just because a local API stopped working. That removes a safety layer and hides the real routing requirement. Add the correct LAN path, test it, then stop Gluetun and confirm the protected application cannot simply escape over the normal host interface.
DNS is part of the privacy path
A changed public IP is not the end of VPN testing. DNS requests can reveal the local resolver path or simply fail if the container stack was designed around a host DNS service that Gluetun can no longer reach. Run a DNS leak test from the connected application network. If the app uses local DNS for internal names, decide whether that is intentional and make the route explicit rather than mixing private and public resolution by accident.
Gluetun has its own DNS capabilities, and Docker hosts can also inject resolvers. Avoid piling several DNS layers together without a plan. Choose which resolver should handle internet names, which resolver should handle local names, and how the container reaches each one. Simple DNS architecture makes VPN troubleshooting much faster.
Test the kill-switch behavior instead of assuming it
Stop Gluetun while the child application is running. The application should not gain a new ordinary internet route just because its gateway disappeared. If it does, the container is not actually bound to the Gluetun network the way you intended. Start Gluetun again, wait for health, and verify the Surfshark public IP returns. Repeat the test after a Docker engine restart or host reboot.
A good deployment also watches the Gluetun health state. If the provider is unreachable or authentication fails, downstream applications may remain running but unable to access the internet. That is safer than leaking, but you still want monitoring so the failure is visible. Reliability is not just uptime. It is predictable behavior during an outage.
Surfshark limitations still apply behind Gluetun
Gluetun cannot grant a feature the VPN provider does not offer. Surfshark does not provide normal VPN port forwarding, so you should not expect Gluetun to create an inbound port on the Surfshark server. Local Docker port publishing still works for devices that can reach the Docker host, but that is a different network layer. A host port does not make the service reachable from the public internet through the VPN exit.
Likewise, a Surfshark Dedicated IP provides a stable exit address but does not automatically become a public inbound service endpoint. If an application depends on provider-side forwarding, choose a different architecture rather than trying to force the requirement through Gluetun firewall settings.
Use Gluetun only where application-level routing adds value
Putting every Docker application behind one commercial VPN can break discovery, local APIs, webhooks and remote services for no benefit. Choose the containers that actually need a different public exit address. A downloader, scraper or region-sensitive client can be a good candidate. Plex, Home Assistant, databases and management dashboards often belong on ordinary local routes unless a specific design says otherwise.
This selective model is especially useful on NAS systems and home servers. Storage can remain stable, backups can use direct routes, and only the privacy-sensitive workload inherits Surfshark. The VPN becomes an application policy rather than a property of the entire machine.
When to choose Gluetun over native host WireGuard
Choose Gluetun when you want a portable Docker pattern across Unraid, Linux, Synology or another container host, when multiple applications should share one VPN stack, or when you value the dedicated firewall and provider selection controls. Choose native host WireGuard when the platform already exposes an easy per-container VPN network and you do not need the extra gateway layer.
Both approaches can be correct. The key is to keep Surfshark in its proper role: an outbound commercial VPN. Remote administration, public inbound services and storage availability should not become accidental dependencies of the VPN container.
Surfshark with Gluetun: Docker WireGuard Setup Guide: questions
Does Gluetun support Surfshark WireGuard?
Yes. Surfshark is a native Gluetun provider and the current setup supports WireGuard.
What is network_mode: service:gluetun?
It tells a container in the same Compose project to use the Gluetun service network stack.
Where do I map ports for a container behind Gluetun?
Map the required host ports on the Gluetun container because it owns the shared network namespace.
Can Gluetun give Surfshark port forwarding?
No. Surfshark does not offer normal VPN port forwarding, so Gluetun cannot create it.
Can Gluetun containers access my LAN?
Yes, when you explicitly allow the needed local subnet with FIREWALL_OUTBOUND_SUBNETS and avoid route overlap.
Primary references used for this guide
Cloudzat checks current Surfshark, Unraid and Gluetun documentation before recommending a VPN route. Provider endpoints, Unraid networking and container images can change, so verify current vendor instructions before modifying a production server.
Research snapshot: August 24, 2026. Recheck current Surfshark, Unraid and Gluetun documentation before changing a production VPN, firewall or Docker network.