How to Setup a Bittorrent client (Transmission) to use a VPN in a docker container

This tutorial will walk you through how to setup a docker container that will automatically start at boot, connect to a VPN, and launch transmission web GUI on CentOS 7.

A big shout out to haugene: . This is the docker container that had everything I needed to get going with transmission and PIA VPN. I should note that haugene supports a TON of other VPNs, so you don’t necessarily need to use PIA, but that’s what I’m using. So let’s get started.

This is already assuming you are root/have sudo access and that docker is installed. If docker isn’t installed, then you should just be able to do a sudo yum -y install docker.

This isn’t the way I initially setup my system, but should make it easier for you.

vi /etc/systemd/system/
Make it look like this:

Description=haugene/transmission-openvpn docker container

ExecStartPre=-/usr/bin/docker kill transmission
ExecStartPre=-/usr/bin/docker rm transmission
ExecStartPre=/usr/bin/docker pull haugene/transmission-openvpn
ExecStart=/usr/bin/docker run \
–name transmission\
-v /Downloads/torrents:/data\
-v /etc/localtime:/etc/localtime:ro\
-p 9091:9091\
-e “TRANSMISSION_DOWNLOAD_DIR=/data/complete/movies”\


You will want to change a few things including the mounting of your local filesystem to to a location inside of the docker container. Above I’m mounting “/Downloads/torrents” to “/data” inside the docker container. You can see below that "TRANSMISSION_DOWNLOAD_DIR="/data/complete/movies, that is relative to the docker container. On your host system, in my case, that would equate to /Downloads/torrents/complete/movies, get it? I Set my config to use “US Texas”, but you should select the one that works the best for your or is the closest. I also set some other options like limiting the speed limit up to “0” (yes, that’s leeching and not nice) and enabled and setting a blocklist. You can set any option that’s in the transmission config. I highly encourage you to RTFM if you want to change/set an option.

If you’re not used to firewalld, it’s pretty simple. But I would highly recommend making sure you have bash completion installed as it makes tab completing the commands MUCH easier (yum install bash-completion).

I left my setup to use the default port 9091, you can change the on your docker host side to be any port you want to forward internally to the transmission container on port 9091.

firewall-cmd --add-masquerade --permanent
firewall-cmd --permanent --add-port=9091/tcp

Note the above --permanent argument, you could run the command without this argument, but whenever you restart firewalld or your system, it won’t persist.

Also, make sure that you restart firewalld so the changes go into effect:
firewall-cmd --reload

After you add that service, you need to re-read all of your service files. If you ever make a change to the transmission.service file, run this command again for them to be “seen” by the system.
sudo systemctl daemon-reload

Then you will want to enable the service at boot:
sudo systemctl enable transmission

Before you start the service, I ran into an issue where transmission was looking for a “watch” directory in the root of the data directory (“/data” for the container, “/Downloads/torrents” for the docker host). So I went ahead and created that:
mkdir -p /Downloads/torrents/watch

Then you can start the service:
sudo systemctl start transmission

You can then browse the IP of the docker host on port 9091 ( and you should see your transmission page:

I wanted to verify that my VPN was actually connecting, so you can download a torrent that will tell you your IP that you’re coming from, I downloaded it from here.

Shameless Plug:

You can compare that to your home NAT’d IP from a website I built here: You can also do a curl against to just get the IP without all of the extra info:
If you want all of the info (sans header info) in JSON format you can change your useragent to “json”:
curl -A json


So let’s pretend that this tutorial isn’t as amazing as you were hoping and it doesn’t work right away, I know, I said pretend.  Part of the fun (at least for me) is getting stuff to work, which means it sometimes has to break for that to happen.


Things to check

Is docker running?
systemctl status docker

If not:
systemctl enable docker; systemctl start docker

Do you see the docker container running?

[root@yourhost /]# docker ps -l
320049380fb3 haugene/transmission-openvpn "dumb-init /etc/openv" 16 hours ago Up 16 hours>9091/tcp transmission

Do you see tranmission running?

Should say active running, if not try to start it again or look at any errors it may have throw.
[root@yourhost /]# systemctl status transmission -l
● transmission.service - haugene/transmission-openvpn docker container
Loaded: loaded (/usr/lib/systemd/system/transmission.service; enabled; vendor preset: disabled)
Active: active (running) since Fri 2017-02-03 18:13:37 MST; 16h ago

Is transmission inside the docker container throwing errors?
Go to your the root of your data drive again, and look for transmission.log. Are there errors? Bad config? An extra space somewhere? Wrong password? Can’t find a directory?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.