The other day, I had the worst customer support experience with a company called NordVPN.
I used their service for over a year for pure convenience; a Docker stack for both their VPN service and qBittorrent exists and runs with a single compose deployment.
I no longer wanted to deal with this company and started looking for alternatives with a similar setup.
I couldn’t find anything turnkey, so I had to create my own.
I’ve chosen Mullvad as my new VPN provider; let’s see how it works out long-term!
Let me show you how to do it; it’s easier than I thought: Mullvad VPN and qBittorrent in Docker.
OpenVPN Container
I’m using this dude:
https://github.com/wfg/docker-openvpn-client
And this is my setup:
version: "2"
services:
openvpn-client:
image: yacht7/openvpn-client
container_name: openvpn-client
cap_add:
- NET_ADMIN
environment:
- KILL_SWITCH=on
- FORWARDED_PORTS=58670
- SUBNETS=10.0.0.0/24
devices:
- /dev/net/tun
volumes:
- /opt/mullvad/data/vpn:/data/vpn
ports:
- 8080:8080
restart: unless-stopped
We need the cap_add as the container requires permissions to create connections.
The killswitch stays on as a security measure, and the subnet is my local subnet so that I can access it.
At the bottom, we’re opening port 8080, which will be passed through to qBittorrent’s web interface later.
But what is the other stuff?
I created a folder on the Docker host at /opt/mullvad/data/vpn and attached it to the container.
Let’s have a look inside:

Get the config files from Mullvad

Over at Mullvad, click My account and enter your unique account number.
Once logged in, go to their OpenVPN configurator.
Select Linux and a country and city of your choice, and download the zip file.

Unzip it and throw the files via SSH into the /vpn folder.
Now we go back to Mullvad and select “Manage devices and ports,” scroll all down, and choose the same city and “no device.”

The result is a random high port, and you add it into the compose file as “forwarded ports.”
Start the container either per CLI or Portainer.
Portainer makes the verification pretty convenient.
Go to the container and select Console:

Make sure to change from bash to /sh:

And paste the following command into the console:
wget http://ipecho.net/plain -O - -q ; echo
The result should be different than https://www.whatismyip.com/
That’s it, and the VPN container part is alive.
qBittorrent Container
The obvious choice is this one.
Is there even an alternative? I don’t think so.
Here’s my compose file:
version: "2.1"
services:
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
container_name: qbittorrent
environment:
- PUID=0
- PGID=0
- TZ=Europe/Berlin
volumes:
- /opt/qbittorrent:/config
- /mnt/downloads:/downloads
network_mode: container:openvpn-client
restart: unless-stopped
depends_on:
- openvpn-client
There are a few things which require special attention.
First, I removed all port-related lines from the original compose files, as we don’t need them here.
We’re forwarding 8080 from the VPN container.
I created a persistent folder for the config files and mapped my downloads folder to the container.
Also, there are two references to the VPN container.
One is the network_mode, telling qBt to talk to the openvpn-client container.
The other is the “depends-on,” another failsafe mechanism.
Before starting downloading another Linux distro via torrent, let’s try the same connection test again from inside the qBt container:

The expected result is the same IP as from inside the openvpn-client container.
And that’s it, really, a few steps but no rocket science.
Update:
Steps with Wireguard added.
More homelab posts:
Google Domains DDclient Dynamic DNS OPNsense
Earlier I wrote about setting up an OPNsense firewall. As I’m using Google Domains, I…
OPNsense IPv6 Telekom Magenta
Ich weiß nicht, wie viele physische und virtuelle Firewalls ich in meinem Homelab in den…
SolarWinds Hybrid Cloud Observability First Steps, part two
Are you ready to continue our first steps in the SolarWinds Hybrid Cloud Observability platform? …
Mullvad Wireguard qBittorrent Docker
Change is a process, or so they say.That applies to a homelab.Two weeks ago, I…
SolarWinds Hybrid Cloud Observability First Steps, part one
I deployed SolarWinds Hybrid Cloud Observability (HCO), and now I have started to adjust it.I…
SolarWinds Hybrid Cloud Observability – Installation
This is a “death by screenshot” style tutorial about a SolarWinds Hybrid Cloud Observability installation.I’m…