Skip to main content
Connect Portainer Agent to Unraid via WireGuard VPN

Connect Portainer Agent to Unraid via WireGuard VPN

Table of Contents

This guide explains how to connect a Portainer Agent securely over a WireGuard VPN to an Unraid server.
The agent runs on an external Linux host (for example, a VPS or dedicated server), while Portainer itself runs on the Unraid system.
All communication between the two systems occurs exclusively through an encrypted VPN tunnel.


Requirements
#

  • Linux server with Docker or Docker Compose
  • Unraid server with Portainer (CE or BE)
  • UDP port 51820 must be reachable from the outside
  • Basic understanding of Docker and UFW

Docker Compose on the Server
#

Create a file named docker-compose.yml on the target server with the following content:

services:
  wireguard:
    image: lscr.io/linuxserver/wireguard:latest
    container_name: wireguard
    restart: always
    network_mode: host
    cap_add:
      - NET_ADMIN
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Berlin
      - SERVERURL=<ip-of-server>
      - SERVERPORT=51820
      - PEERS=1
      - PEERDNS=auto
    volumes:
      - ./wireguard:/config
      - /lib/modules:/lib/modules

  portainer-agent:
    image: portainer/agent:latest
    container_name: portainer-agent
    restart: always
    network_mode: host
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/lib/docker/volumes:/var/lib/docker/volumes
      - /:/host

Notes:

  • Ensure the path /lib/modules is correct (not /lib/nodules).
  • Set SERVERURL to your public IP or DNS hostname.
  • Increase PEERS if you plan to connect multiple clients.

Start the containers:

docker compose up -d

Prevent Docker from Modifying iptables Automatically
#

By default, Docker modifies iptables rules and opens ports automatically when containers start. This can result in containers being accessible from the public network even if UFW is active. To retain full control over firewall rules, disable this behavior.

Create or edit the Docker daemon configuration file /etc/docker/daemon.json:

sudo mkdir -p /etc/docker
sudo nano /etc/docker/daemon.json

Add the following content:

{
  "iptables": false
}

Restart Docker:

sudo systemctl restart docker

Verify:

docker info | grep IPTables

Expected output:

IPTables: false

From now on, Docker will no longer modify iptables automatically. All firewall rules must be managed manually, which in this setup is handled entirely through UFW.


Firewall Configuration (UFW)
#

WireGuard and the Portainer Agent require specific ports to be accessible. Allow only the necessary ports and interfaces:

sudo ufw allow 51820/udp
sudo ufw allow in on wg0 to any port 9001 proto tcp
sudo ufw deny in on docker0 from any to any
sudo ufw reload
Example UFW Firewall
Example UFW Firewall

With these rules, the Portainer Agent is reachable only through the VPN interface (wg0), not via the public network interface (eth0). The docker0 bridge is explicitly blocked to isolate non-host-networked containers from external access.

Check the active rules:

sudo ufw status verbose

Setting Up the WireGuard Client on Unraid
#

After starting the WireGuard container on the server, a client configuration file is generated in the mounted directory, for example:

./wireguard/peer1/peer1.conf

This file contains the client’s private key and network parameters. Copy the file to your Unraid system and import it via:

Settings → VPN Manager → Add Tunnel → Import tunnel from file

Unraid VPN
Unraid VPN

Once imported, activate the connection and verify that it’s up:

wg show

Example output:

peer: <PublicKey>
endpoint: <server-ip>:51820
allowed ips: 10.13.13.0/24
latest handshake: 10 seconds ago
transfer: 12.1 KiB received, 8.4 KiB sent

If the connection does not establish, verify your firewall, ports, and container logs.


Connecting to the Portainer Agent
#

Once the VPN connection is active, the Portainer Agent can be reached through its WireGuard IP. By default, the LinuxServer.io WireGuard image uses the subnet 10.13.13.0/24, where the server usually takes the address 10.13.13.1.

In Portainer (on Unraid):

  1. Go to Environments → Add Environment → Agent

  2. Enter the Agent Address:

    10.13.13.1:9001
    
  3. Save and test the connection.

If successful, the new remote agent should appear in the environment list.


Troubleshooting
#

VPN connection fails:

  • Check logs: docker logs wireguard
  • Verify firewall rules: sudo ufw status
  • Ensure UDP port 51820 is reachable.

Portainer cannot connect to agent:

  • Test connectivity: ping 10.13.13.1 or nc -zv 10.13.13.1 9001
  • Verify container status: docker ps
  • Add PersistentKeepalive = 25 to the Unraid peer configuration if the VPN disconnects periodically.

Incorrect IP or subnet:

  • Adjust the subnet in wireguard/config/wg0.conf if needed.
  • Restart the containers after making changes.

Example Directory Layout
#

/opt/portainer-vpn/
├── docker-compose.yml
└── wireguard/
    ├── server.conf
    ├── peer1/
    │   └── peer1.conf

Summary
#

With this setup, the Portainer Agent operates securely behind a WireGuard VPN tunnel. Docker no longer opens ports automatically, and all network traffic is controlled via UFW. The agent is only accessible through the VPN interface, making remote Docker host management via Portainer both secure and predictable.

Florian Hoss
Author
Florian Hoss