This section describes how to prepare and build Docker image for the Transmission.
Create a transmission
directory under the /root/silverbox/vpn
directory:
sudo mkdir /root/silverbox/vpn/transmission sudo chmod 700 /root/silverbox/vpn/transmission
And copy all OpenVPN profile files (*.ovpn
) that you want to use for Transmission client into it
(you can have multiple files as exit point rotation will be configured).
This way you can use different OpenVPN profiles (and thus exit points) for SOCKS5 proxy and for Transmission.
Note
|
At any time, if you want only to use specific profile, create a symlink named profile pointing to desired
profile. For example ln -s SOME_PROFILE.ovpn profile .
Make sure the link is relative and not absolute: otherwise it won’t work inside the container.
|
In this configuration, Transmission will use directories on the NFS share to read torrent files and to store downloaded files. These directories need to be created in advance.
As your user, create directories for torrent files and downloads in the NFS directory and set proper permissions/ownership:
mkdir -p /srv/nfs/torrents/torrentfiles # (1) mkdir -p /srv/nfs/torrents/downloads # (2) chown {SB_USER}:{SB_NFS_GROUP} -R /srv/nfs/torrents chmod 770 -R /srv/nfs/torrents
-
This directory will be automatically watched for the
*.torrent
files and once new file appear download will be started automatically (torrent file will be removed once added to the queue). -
Finished and in-progress downloads will be placed into this directory.
Note
|
Of course, you can use different directory structure and names, this is just an example. |
Create a directory for the Transmission container:
sudo mkdir /root/silverbox/containers/transmission sudo chmod 700 /root/silverbox/containers/transmission
Inside the transmission
directory, create a file named docker-compose.yaml
with the following content:
version: '3.8'
networks:
default:
name: vpn
external: true
services:
transmission:
container_name: transmission
init: true
build:
context: /root/silverbox/containers/transmission
args:
version: '{SB_DEBIAN_VERSION}' # (1)
restart: on-failure:15
logging:
driver: json-file
options:
max-size: 10mb
ports:
- 127.0.0.1:{SB_TRANSMISSION_PORT}:{SB_TRANSMISSION_PORT}/tcp # (2)
networks:
default:
ipv4_address: {SB_TRANSMISSION_ADDR} # (3)
devices:
- /dev/net/tun
cap_add:
- NET_ADMIN
volumes:
- /srv/nfs/torrents:/data
- /root/silverbox/vpn/transmission:/vpn-profiles
- /root/silverbox/vpn/auth:/vpn-credentials
-
Replace
{SB_DEBIAN_VERSION}
with the actual latestdebian
image version (can be checked at the Docker Hub). Note that this is not the Transmission version. -
Replace
{SB_TRANSMISSION_PORT}
with the actual port number. -
Replace
{SB_TRANSMISSION_ADDR}
with the actual address.
Next, create a file named Dockerfile
with the following content:
ARG version=latest
FROM debian:$version
ARG UID={USER_ID} # (1)
ARG GID={GROUP_ID} # (2)
RUN apt-get update && \
apt-get install -y --no-install-recommends bash iputils-ping iptables openvpn transmission-daemon && \
addgroup --system vpn && \
addgroup --gid ${GID} transmission && \
adduser transmission --uid ${UID} --gid ${GID} --disabled-login --no-create-home --gecos "" --shell /usr/sbin/nologin && \
mkdir /config && chown transmission:transmission /config
COPY docker-entrypoint.sh /usr/local/bin/
COPY start-transmission.sh /usr/local/bin/
COPY --chown=transmission:transmission settings.json /config/
HEALTHCHECK --interval=120s --timeout=20s --start-period=120s CMD ping 1.1.1.1 -c 1 # (3)
VOLUME ["/vpn-profiles", "/vpn-credentials", "/data"]
EXPOSE {SB_TRANSMISSION_PORT}/tcp # (4)
ENTRYPOINT [ "/usr/local/bin/docker-entrypoint.sh" ]
-
Replace
{USER_ID}
with the UID of your{SB_USER}
user on the server. -
Replace
{GROUP_ID}
with the GID of your{SB_NFS_GROUP}
group on the server. -
Feel free to customize health check command.
-
Replace
{SB_TRANSMISSION_PORT}
with some port number of your choice (e.g. 12345). The container will expose this port to access the Transmission web UI.
Create the start-transmission.sh
file with the following content:
#!/bin/bash
echo "-- Preparing to start transmission-daemon..."
if [ -f /config/transmission.log ]; then
echo "-- Cleaning log file..."
tail -c 10000000 /config/transmission.log > /config/transmission.log.trunc
mv /config/transmission.log.trunc /config/transmission.log
chown transmission:transmission /config/transmission.log
fi
TUN_IP=$(ip address show dev tun0 | awk '/inet/{ split($2, a, "/"); print a[1] }')
if [ -z "$TUN_IP" ]; then
echo "-- Failed to get tun0 IP address"
exit 1
else
echo "-- tun0 address: [$TUN_IP]. Updating config file."
sed -i "s/\(\"bind-address-ipv4\":\)\s\+\".\+\",/\1 \"$TUN_IP\",/" /config/settings.json
echo "-- Starting transmission-daemon..."
su transmission -s /bin/bash -c "transmission-daemon -g /config --logfile /config/transmission.log"
if [ $? -ne 0 ]; then
echo "-- Failed to start transmission"
exit 1
else
echo "-- Transmission started"
fi
fi
And mark it as executable:
sudo chmod a+x start-transmission.sh
Create the docker-entrypoint.sh
file with the following content:
#!/usr/bin/env bash
function configure_iptables()
{
set -e
local config_file="$1"
local host=$(awk '/^remote / {print $2}' "$config_file")
local port=$(awk '/^remote / && NF ~ /^[0-9]*$/ {print $NF}' "$config_file")
if [ -z "$port" ]; then
echo "-- No port number specified in the VPN profile file"
exit 1
else
echo "-- Setting up firewall rules for VPN server $host on port $port"
fi
iptables --flush
iptables --delete-chain
iptables --policy INPUT DROP
iptables --policy OUTPUT DROP
iptables --policy FORWARD DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i tun0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s $host --sport $port -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -s {VPN_NETWORK_GW} --dport {SB_TRANSMISSION_PORT} -j ACCEPT # (1)
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A OUTPUT -o tun0 -j ACCEPT
iptables -A OUTPUT -o eth0 -d {VPN_NETWORK_GW} -p tcp --sport {SB_TRANSMISSION_PORT} -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # (2)
iptables -A OUTPUT -o eth0 -p tcp -d $host --dport $port -m owner --gid-owner vpn -j ACCEPT
set +e
}
if [[ $# -ge 1 ]]; then
exec "$@"
else
if [ -f /vpn-profiles/profile ]; then
echo "-- Profile file found: only it will be used"
PROFILE_FILE="/vpn-profiles/profile"
else
echo "-- Profile file not found: random profile file will be picked"
PROFILE_FILE="$(ls -1 /vpn-profiles/*.ovpn | shuf -n 1)"
echo "-- Selected profile file: $PROFILE_FILE"
fi
configure_iptables "$PROFILE_FILE"
exec sg vpn -c "openvpn --config $PROFILE_FILE --verb 1 --auth-user-pass /vpn-credentials/credentials --auth-nocache --script-security 2 --route-up /usr/local/bin/start-transmission.sh"
fi
-
Replace
{VPN_NETWORK_GW}
with the default gateway address of your VPN Docker network{SB_VPN_SUBNET}
. For example, if your{SB_VPN_SUBNET}
is172.18.0.0/24
the gateway address would be172.18.0.1
. Also, replace{SB_TRANSMISSION_PORT}
with the actual port number. -
Same as above.
Mark this script as executable:
sudo chmod a+x docker-entrypoint.sh
Finally, create the settings.json
file with the following content:
{
"rpc-enabled": true,
"rpc-bind-address": "{SB_TRANSMISSION_ADDR}", # (1)
"rpc-port": {SB_TRANSMISSION_PORT}, # (2)
"rpc-whitelist": "{VPN_NETWORK_GW}", # (3)
"rpc-whitelist-enabled": true,
"alt-speed-enabled": false,
"speed-limit-down-enabled": true,
"speed-limit-down": 2500,
"speed-limit-up-enabled": true,
"speed-limit-up": 200,
"blocklist-enabled": false,
"download-dir": "/data/downloads",
"incomplete-dir-enabled": false,
"rename-partial-files": true,
"start-added-torrents": true,
"trash-original-torrent-files": true,
"watch-dir-enabled": true,
"watch-dir": "/data/torrentfiles",
"umask": 7,
"cache-size-mb": 16,
"prefetch-enabled": true,
"encryption": 1,
"message-level": 2,
"dht-enabled": true,
"lpd-enabled": false,
"pex-enabled": true,
"utp-enabled": false,
"bind-address-ipv4": "127.0.0.1",
"peer-limit-global": 100,
"peer-limit-per-torrent": 40,
"peer-congestion-algorithm": "",
"peer-port": 51413,
"peer-port-random-on-start": false,
"port-forwarding-enabled": false,
"download-queue-enabled": true,
"download-queue-size": 5,
"queue-stalled-enabled": true,
"queue-stalled-minutes": 30,
"seed-queue-enabled": true,
"seed-queue-size": 3,
"alt-speed-time-enabled": false,
"idle-seeding-limit-enabled": false,
"ratio-limit-enabled": true,
"ratio-limit": 1.2
}
-
Replace
{SB_TRANSMISSION_ADDR}
with some address from the{SB_VPN_SUBNET}
that Transmission container will be running on. -
Replace
{SB_TRANSMISSION_PORT}
with the actual port number. Make sure this is number and not string in quotes. -
Replace
{VPN_NETWORK_GW}
with the actual address.
Note
|
Feel free to adjust the values in the settings.json file according to your needs.
|