Skip to content

Transmission with WireGuard

Description / nameInput element
Container Registry
Container Configuration Root Path
Global /downloads Path
Timezone
User ID
Group ID
Transmission with WireGuard Host Port
Transmission with WireGuard /config Path
Transmission with WireGuard /watch Path

Build Status Last Commit

Transmission BitTorrent client with built-in WireGuard VPN support.

Port 9091
Registry ghcr.io/daemonless/transmission-wireguard
Source https://github.com/transmission/transmission
Website https://transmissionbt.com/

Version Tags

Tag Description Best For
latest / pkg FreeBSD Quarterly. Uses stable, tested packages. Most users. Matches Linux Docker behavior.
pkg-latest FreeBSD Latest. Rolling package updates. Newest FreeBSD packages.

Root Privileges Required

Podman on FreeBSD currently requires root. All commands must be run as root (or via doas/sudo).

Before deploying, ensure your host environment is ready. See the Quick Start Guide for host setup instructions.

Deployment

services:
  transmission-wireguard:
    image: ghcr.io/daemonless/transmission-wireguard:latest
    container_name: transmission-wireguard
    environment:
      - WG_PRIVATE_KEY=your-private-key
      - WG_PEER_PUBLIC_KEY=vpn-server-public-key
      - WG_ENDPOINT=vpn.example.com:51820
      - WG_ADDRESS=10.5.0.2/32
      - WG_DNS=1.1.1.1
      - PUID=1000
      - PGID=1000
      - TZ=UTC
    volumes:
      - "/path/to/containers/transmission-wireguard:/config"
      - "/path/to/downloads:/downloads"
      - "/path/to/containers/transmission-wireguard/watch:/watch"
    ports:
      - 9091:9091
      - 51413:51413
      - 51413:51413
    restart: unless-stopped

.env:

DIRECTOR_PROJECT=transmission-wireguard
WG_PRIVATE_KEY=your-private-key
WG_PEER_PUBLIC_KEY=vpn-server-public-key
WG_ENDPOINT=vpn.example.com:51820
WG_ADDRESS=10.5.0.2/32
WG_DNS=1.1.1.1
PUID=1000
PGID=1000
TZ=UTC

appjail-director.yml:

options:
  - virtualnet: ':<random> default'
  - nat:
services:
  transmission-wireguard:
    name: transmission_wireguard
    options:
      - container: 'boot args:--pull'
    oci:
      user: root
      environment:
        - WG_PRIVATE_KEY: !ENV '${WG_PRIVATE_KEY}'
        - WG_PEER_PUBLIC_KEY: !ENV '${WG_PEER_PUBLIC_KEY}'
        - WG_ENDPOINT: !ENV '${WG_ENDPOINT}'
        - WG_ADDRESS: !ENV '${WG_ADDRESS}'
        - WG_DNS: !ENV '${WG_DNS}'
        - PUID: !ENV '${PUID}'
        - PGID: !ENV '${PGID}'
        - TZ: !ENV '${TZ}'
    volumes:
      - TRANSMISSION_WIREGUARD_CONFIG_PATH: /config
      - DOWNLOADS_PATH: /downloads
      - TRANSMISSION_WIREGUARD_WATCH_PATH: /watch
volumes:
  TRANSMISSION_WIREGUARD_CONFIG_PATH:
    device: '/path/to/containers/transmission-wireguard'
  DOWNLOADS_PATH:
    device: '/path/to/downloads'
  TRANSMISSION_WIREGUARD_WATCH_PATH:
    device: '/path/to/containers/transmission-wireguard/watch'

Makejail:

ARG tag=latest

OPTION overwrite=force
OPTION from=ghcr.io/daemonless/transmission-wireguard:${tag}
podman run -d --name transmission-wireguard \
  -p 9091:9091 \
  -p 51413:51413 \
  -p 51413:51413 \
  -e WG_PRIVATE_KEY=your-private-key \
  -e WG_PEER_PUBLIC_KEY=vpn-server-public-key \
  -e WG_ENDPOINT=vpn.example.com:51820 \
  -e WG_ADDRESS=10.5.0.2/32 \
  -e WG_DNS=1.1.1.1 \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=UTC \
  -v /path/to/containers/transmission-wireguard:/config \
  -v /path/to/downloads:/downloads \
  -v /path/to/containers/transmission-wireguard/watch:/watch \
  ghcr.io/daemonless/transmission-wireguard:latest
- name: Deploy transmission-wireguard
  containers.podman.podman_container:
    name: transmission-wireguard
    image: ghcr.io/daemonless/transmission-wireguard:latest
    state: started
    restart_policy: always
    env:
      WG_PRIVATE_KEY: "your-private-key"
      WG_PEER_PUBLIC_KEY: "vpn-server-public-key"
      WG_ENDPOINT: "vpn.example.com:51820"
      WG_ADDRESS: "10.5.0.2/32"
      WG_DNS: "1.1.1.1"
      PUID: "1000"
      PGID: "1000"
      TZ: "UTC"
    ports:
      - "9091:9091"
      - "51413:51413"
      - "51413:51413"
    volumes:
      - "/path/to/containers/transmission-wireguard:/config"
      - "/path/to/downloads:/downloads"
      - "/path/to/containers/transmission-wireguard/watch:/watch"

Access at: http://localhost:9091

Interactive Configuration

Parameters

Environment Variables

Variable Default Description
WG_PRIVATE_KEY your-private-key Your WireGuard private key
WG_PEER_PUBLIC_KEY vpn-server-public-key VPN server's public key
WG_ENDPOINT vpn.example.com:51820 VPN server address (host:port)
WG_ADDRESS 10.5.0.2/32 Your tunnel IP address (default: 10.5.0.2/32)
WG_DNS 1.1.1.1 DNS server to use (default: 1.1.1.1)
PUID 1000 User ID for the application process
PGID 1000 Group ID for the application process
TZ UTC Timezone for the container

Volumes

Path Description
/config Configuration directory (settings.json, WireGuard configs)
/downloads Download directory
/watch Watch directory for torrent files

Ports

Port Protocol Description
9091 TCP Web UI
51413 TCP Torrent traffic (TCP/UDP)
51413 UDP Torrent traffic (TCP/UDP)

WireGuard Setup

Host Requirements

Load the WireGuard kernel module on the host:

kldload if_wg
echo 'if_wg_load="YES"' >> /boot/loader.conf

VNET Required

This container requires its own network stack. Add the annotation:

--annotation 'org.freebsd.jail.vnet=new'

Getting VPN Credentials

From your VPN provider (Mullvad, PIA, ProtonVPN, etc.), get: - Private Key - Your client private key - Public Key - The VPN server's public key - Endpoint - Server address like vpn.example.com:51820 - Address - Your assigned tunnel IP

Kill Switch

Traffic is routed through the VPN interface. If the VPN connection drops, Transmission loses connectivity - no IP leaks.

Verifying VPN

Check your public IP from inside the container:

podman exec transmission-wireguard fetch -qo - https://ifconfig.me

Implementation Details

  • Architectures: amd64
  • User: bsd (UID/GID set via PUID/PGID). Defaults to 1000:1000.
  • Base: Built on ghcr.io/daemonless/base (FreeBSD 15.0).

Need help? Join our Discord community.