Examples - thrnz/docker-wireguard-pia GitHub Wiki

Here are some working examples showing some ways in which the container can be used. If you've got an interesting use for the container, or have something that someone else might find useful, feel free to add it below.

SOCKS5 proxy accessible from the LAN

Note that the socks-proxy container essentially inherits the network stack of the vpn container, so things like ports are set on the vpn container itself.

services:
    vpn:
        image: thrnz/docker-wireguard-pia
        volumes:
            - pia-dat:/pia
        ports:
            - 1080:1080
        cap_add:
            - NET_ADMIN
        environment:
            - LOCAL_NETWORK=192.168.1.0/24
            - LOC=swiss
            - USER=xxxx
            - PASS=xxxx
        sysctls:
            - net.ipv4.conf.all.src_valid_mark=1

    socks-proxy:
        image: serjs/go-socks5-proxy
        network_mode: "service:vpn"

volumes:
    pia-dat:

Bittorrent client with port forwarding

Normally qBittorent would need the listen port to be manually set to the port number shown in the vpn container's logs. This can be automated by scripting using the PORT_SCRIPT env var. Note that access to the web ui port is exposed on the vpn container itself, and that LOCAL_NETWORK must be set correctly for access from other machines on the lan.

services:
    vpn:
        image: thrnz/docker-wireguard-pia
        volumes:
            - pia-dat:/pia
            - /path/to/set_qbt_port.sh:/set_qbt_port.sh
        ports:
            - 8080:8080
        cap_add:
            - NET_ADMIN
        environment:
            - LOCAL_NETWORK=192.168.1.0/24
            - LOC=swiss
            - USER=xxxx
            - PASS=xxxx
            - PORT_FORWARDING=1
            - PORT_SCRIPT=/set_qbt_port.sh
        sysctls:
            - net.ipv4.conf.all.src_valid_mark=1

    qbittorrent:
        image: lscr.io/linuxserver/qbittorrent:latest
        network_mode: "service:vpn"
        volumes:
            - /path/to/appdata/config:/config
            - /path/to/downloads:/downloads

volumes:
    pia-dat:

The following script can be customized as needed then mounted inside the container and automatically run by setting the PORT_SCRIPT=/set_qbt_port.sh env var. Ensure that the correct permissions are set first ( chmod +x /path/to/set_qbt_port.sh).

#!/bin/bash

# The forwarded port is passed as the first argument to the script
port="$1"
qbt_user="admin"
qbt_pass="password"
qbt_port="8080"

curl_params="--silent --retry 10 --retry-delay 15 --max-time 10 --retry-all-errors"

echo "$(date): Setting qBittorrent listen port to $port..."

curl $curl_params \
  --data-urlencode "username=${qbt_user}" \
  --data-urlencode "password=${qbt_pass}" \
  --output /dev/null \
  --cookie-jar /tmp/qb-cookies.txt \
  http://localhost:${qbt_port}/api/v2/auth/login

curl $curl_params \
  --data 'json={"listen_port": "'"$port"'"}' \
  --output /dev/null \
  --cookie /tmp/qb-cookies.txt \
  http://localhost:${qbt_port}/api/v2/app/setPreferences

if [[ $(curl $curl_params --cookie /tmp/qb-cookies.txt \
  http://localhost:${qbt_port}/api/v2/app/preferences | jq '.listen_port') = "$port" ]]; then
  echo "$(date): qBittorrent listen port successfully set to $port"
else
  echo "$(date): Error: qBittorrent port was not set"
fi

See Issue #26 for a bit more info, including links to scripts for some other clients.

Another option is to use the PORT_FILE env var. By default the container dumps the forwarded port number to /pia-shared/port.dat which can then be mounted and monitored in other containers. Some 'helper' containers have been made for setting the listen port in qBittorrent, Transmission, and Deluge. For instance, the qBittorrent helper container example can be used as follows:

    image: scotte/qbittorrent-porthelper:latest
    container_name: qbittorrent-porthelper
    environment:
      - HOST=192.168.10.254:8080
      - USERNAME=YourqBittorrentUsernameHere
      - PASSWORD=YourqBittorrentPasswordHere
    volumes:
      - /data/software/wireguard-pia/:/piashared
    depends_on:
      - qbittorrent

MeTube (yt-dlp web gui)

See https://github.com/alexta69/metube for more info on config.

version: '3'
services:
  vpn:
    image: thrnz/docker-wireguard-pia
    restart: unless-stopped
    container_name: vpn
    hostname: vpn
    volumes:
      - /appdata/pia-metube/pia:/pia
      - /appdata/pia-metube/pia-shared:/pia-shared 
    cap_add:
      - NET_ADMIN
      - SYS_MODULE # SYS_MODULE might not be needed with a 5.6+ kernel?
    ports:
      - 8081:8081 # MeTube port
    environment:
      # Streaming optimized PIA locations
      # ca_ontario-so | us-streaming | us-streaming-2 | de_germany-so | japan_2 | sweden_2 | uk_2 | au_australia-so
      - LOC=${pia_loc}
      - USER=${pia_user}
      - PASS=${pia_pass}
      - VPNDNS=1.1.1.1,1.0.0.1
      - LOCAL_NETWORK=192.168.1.0/24
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
      - net.ipv6.conf.default.disable_ipv6=1
      - net.ipv6.conf.all.disable_ipv6=1
      - net.ipv6.conf.lo.disable_ipv6=1
  metube_vpn:
    image: ghcr.io/alexta69/metube
    container_name: metube_vpn
    restart: unless-stopped
    volumes:
      - /downloads:/downloads
    environment:
      PUID: "99"
      PGID: "100"
      TZ: America/Chicago
      UMASK: "000"
      DEFAULT_THEME: dark
      OUTPUT_TEMPLATE: "%(channel)s [%(channel_id)s]/%(title)s [%(id)s]/%(title)s.%(ext)s"
      OUTPUT_TEMPLATE_PLAYLIST: "%(playlist_title)s[%(playlist_id)s]/%(title)s
        [%(id)s]/%(title)s.%(ext)s"
      YTDL_OPTIONS: |
        {
          "format": "bv+ba/b",
          "postprocessors": [
            {
              "key":"FFmpegEmbedSubtitle",
              "already_have_subtitle":false
            },
            {
              "key":"FFmpegThumbnailsConvertor",
              "format":"jpg",
              "when":"before_dl"
            },
            {
              "key":"FFmpegMetadata",
              "add_chapters":true,
              "add_metadata":true,
              "add_infojson":false
            }
          ],
          "restrictfilenames": true,
          "subtitleslangs": [ "en" ],
          "updatetime":false,
          "writedescription": false,
          "writeinfojson": true,
          "writesubtitles": true,
          "writethumbnail": true
        }
    network_mode: service:vpn
    depends_on:
      - vpn

Slskd (Soulseek Web UI)

See https://github.com/slskd/slskd/ for further config. Though multiple instances of docker-wireguard-pia are already discussed in this wiki, it does not outline how to run multiple instances in order to have multiple ports forwarded, such as running qbittorrent and soulseek with port forwarding simultaneously. Specifically, it does not show how to utilise the PORT_SCRIPT for usage with other containers in terms of manually editing config files rather than through an api. This can also be used for other services that may require port forwarding, however, a separate instance must be run for each service that needs to be port forwarded. For example, if you had three different services that needed to be port forwarded, you must run three separate instances of docker-wireguard-pia in order for all three to function properly (only one service can use a given port at a time). Before you do this, ensure that the docker-wireguard-pia application storage /pia, is set to a different path, such as /pia-slskd, so as not to interfere with the application storage of the first instance, if you have an existing instance. Note that for the case of slskd, the web ui is exposed on the VPN container, so the LOCAL_NETWORK must be set correctly to access the container on the LAN. This example assumes that you have an existing instance of Bittorrent client with port forwarding running alongside this one, but the same steps apply if this is your only instance.

services:
  vpn:
    image: thrnz/docker-wireguard-pia:latest
    container_name: docker-slskd-pia
    networks:
      - pia-slskd-net
    ports:
      - 5031:5031 # slskd HTTP web ui port
      - 5030:5030 # slskd HTTPS web ui port
      - 50300:50300 # Default slskd listening port
    cap_add:
      - NET_ADMIN
      - NET_RAW
    sysctls:
      net.ipv4.conf.all.src_valid_mark: 1
      net.ipv6.conf.default.disable_ipv6: 1
      net.ipv6.conf.all.disable_ipv6: 1
      net.ipv6.conf.lo.disable_ipv6: 1
    environment:
      - PUID=0
      - PGID=0
      - USER=${pia_user}
      - PASS=${pia_pass}
      - LOC=${pia_loc}
      - LOCAL_NETWORK=192.168.1.0/24 # Change this to your LAN
      - KEEPALIVE=25
      - PORT_FORWARDING=1
      - WG_USERSPACE=1
      - PORT_PERSIST=1
      - PORT_SCRIPT=/slskd.sh
      - FIREWALL=1
      - PORT_FILE_CLEANUP=1
      - VPNDNS=8.8.8.8,8.8.4.4
    restart: always
    volumes:
      - /docker/data/slskd:/docker/data/slskd # slskd application storage
      - /path/to/slskd.sh:/slskd.sh # Path to slskd.sh script
      - /docker/data/pia-slskd:/pia # pia application storage
    healthcheck: # Includes healthcheck that occasionally pings google.com to ensure VPN is running
      test: ping -c 1 www.google.com || exit 1
      interval: 30s
      timeout: 10s
      retries: 3
  slskd:
    image: slskd/slskd
    container_name: slskd
    environment:
      - SLSKD_REMOTE_CONFIGURATION=true
      - SLSKD_SHARE_CACHE_STORAGE_MODE=memory
    volumes:
      - /docker/data/slskd/:/app # slskd application storage
      - /mnt/storage/data:/mnt/storage/data # Path to music folder
    restart: always
    user: 1001:1001
    network_mode: "service:vpn"
    depends_on: # Ensures slskd starts when PIA is healthy
      vpn:
        condition: service_healthy

networks: # Sets bridge network and names properly
  pia-slskd-net: # Edit to bridge name
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: br-piaslskd # Edit to desired name. This name is what is seen on the system.

The following script can be customized for other services. This script works by manually editing the slskd.yml and looking for listen_port: and changing it to the port being forwarded using sed. Note that the SLSKD variable must be changed to your slskd.yml path.

#!/bin/bash

port="$1"
SLSKD="/path/to/slskd.yml" # Set to path to slskd.yml

sed -i "s/^\(\s*listen_port:\s*\).*/\1$port/" "$SLSKD"

# Print slskd updated port
echo "*slskd* updated with port $port"