Creating a Seedbox: ruTorrent and Plex under Docker

Creating a Seedbox: ruTorrent and Plex under Docker
Jérémie Kassianoff
May 9, 2015
7 min read

A seedbox can be long and tedious to set up. Discover an easier, more flexible way with Docker.

Real-world use case

You want a ready-to-use seedbox without the complexity: here's how to deploy ruTorrent and Plex together under Docker.

Article updated on March 5, 2017 : ruTorrent script update and Plex Docker project update

Creating a seedbox: ruTorrent and Plex under Docker

Switching dedicated servers has become a common practice. Over time, we adapt to what's on the market, since offers evolve and are generally more appealing from one year to the next. The trend is to always pay less while keeping decent hardware specs. A seedbox is always meant to be cheaper for more power.

But when it comes time for the initial configuration, you quickly realize it's tied to its environment and isn't easily changeable. So do you need to recreate it every time you switch servers? The goal of this article is to use Docker's power to solve this problem.

Let's remember that a seedbox's configuration generally includes two services:

  • The download server on one side (example: ruTorrent, Deluge, Transmission…).
  • The streaming server on the other (example: Plex, Kodi…).

Info: An SFTP or FTPES server could also be set up, but I won't cover that in this article.

Discover for yourself:

  1. Docker with: dockertorrent and pms-docker.
  2. Preparing the environment on Debian 8.
  3. Running and configuring dockertorrent.
  4. Running and configuring pms-docker.

Docker with dockertorrent and pms-docker

Docker isolates processes in containers, it's by far the best solution for deploying your projects faster and more easily. It also guarantees increased security as well as unprecedented stability and scalability. It's entirely based on Linux's power. For the following article, I'm going to use two existing Docker projects:

  1. The first is named docktorrent, by author kfei, which contains rTorrent with ruTorrent.
  2. The second is pms-docker, from Plex itself, which contains the PMS (PlexMediaServer) server.

Info: We'll now be able to deploy a seedbox in 5 minutes after our first build. The following article is based on projects that are open on the web, I take no responsibility in case of misuse.

Preparing the environment on Debian 7

Before starting, installing the prerequisites is essential, you'll need the wheezy-backports repository:

bash
nano /etc/apt/sources.list

Add the following repository:

bash
deb http://http.debian.net/debian wheezy-backports main

Update the packages, then install the image, and reboot the server:

bash
apt-get update && apt-get install -t wheezy-backports linux-image-amd64 && reboot

After the system reboot, get ready to install docker:

bash
apt-get install curl git && curl -sSL https://get.docker.com/ | sh

Create two directories to hold the data location for our two users:

bash
mkdir /home/seedbox/user1 && mkdir /home/seedbox/user2

Running and configuring docktorrent

Cloning the docktorrent project with git:

bash
git clone https://github.com/kfei/docktorrent

Move into the archive:

bash
cd docktorrent

At this point, edit rtorrent's configuration file:

bash
nano config/rtorrent/.rtorrent.rc

Personally, I comment out lines 23 and 24, since I don't want to move my files after downloading:

bash
#system.method.insert = d.get_finished_dir,simple,"cat=/rtorrent/finished/,$d.get_custom1="
#system.method.set_key = event.download.finished,move_complete,"d.set_directory=$d.get_finished_dir=;execute=mkdir,-p,$d.get_finished_dir=;execute=mv,-u,$d.get_base_path=,$d.get_finished_dir="

Go to the Dockerfile and change the credential pair:

dockerfile
RUN htpasswd -cb /usr/share/nginx/html/rutorrent/.htpasswd user1 passworduser1

Before starting the build, an error has appeared since December 2016 when building the container:

bash
xmlrpc_libxml2.c: In function 'xml_init':
xmlrpc_libxml2.c:61:29: warning: unused parameter 'envP' [-Wunused-parameter]
 xml_init(xmlrpc_env * const envP) {
                             ^
xmlrpc_libxml2.c: At top level:
xmlrpc_libxml2.c:430:20: error: unknown type name 'xmlParserCtx'
 removeDocSizeLimit(xmlParserCtx * const parserP ATTR_UNUSED) {
                    ^
xmlrpc_libxml2.c:455:14: error: unknown type name 'xmlParserCtx'
              xmlParserCtx ** const parserPP) {
              ^
xmlrpc_libxml2.c: In function 'xml_parse':
xmlrpc_libxml2.c:491:5: warning: implicit declaration of function 'createParser' [-Wimplicit-function-declaration]
     createParser(envP, &context, &parserP);
     ^
make[1]: *** [xmlrpc_libxml2.o] Error 1
/usr/local/src/xmlrpc-c/common.mk:336: recipe for target 'xmlrpc_libxml2.o' failed
make[1]: Leaving directory '/usr/local/src/xmlrpc-c/src'
/usr/local/src/xmlrpc-c/common.mk:375: recipe for target 'src/all' failed
make: *** [src/all] Error 2
The command '/bin/sh -c build_deps="automake build-essential ca-certificates libc-ares-dev libcppunit-dev libtool";     build_deps="${build_deps} libssl-dev libxml2-dev libncurses5-dev pkg-config subversion wget";     set -x &&     apt-get update && apt-get install -q -y --no-install-recommends ${build_deps} &&     wget http://curl.haxx.se/download/curl-7.39.0.tar.gz &&     tar xzvfp curl-7.39.0.tar.gz &&     cd curl-7.39.0 &&     ./configure --enable-ares --enable-tls-srp --enable-gnu-tls --with-zlib --with-ssl &&     make &&     make install &&     cd .. &&     rm -rf curl-* &&     ldconfig &&     svn --trust-server-cert checkout https://svn.code.sf.net/p/xmlrpc-c/code/stable/ xmlrpc-c &&     cd xmlrpc-c &&     ./configure --enable-libxml2-backend --disable-abyss-server --disable-cgi-server &&     make &&     make install &&     cd .. &&     rm -rf xmlrpc-c &&     ldconfig &&     wget -O libtorrent-$VER_LIBTORRENT.tar.gz https://github.com/rakshasa/libtorrent/archive/$VER_LIBTORRENT.tar.gz &&     tar xzf libtorrent-$VER_LIBTORRENT.tar.gz &&     cd libtorrent-$VER_LIBTORRENT &&     ./autogen.sh &&     ./configure --with-posix-fallocate &&     make &&     make install &&     cd .. &&     rm -rf libtorrent-* &&     ldconfig &&     wget -O rtorrent-$VER_RTORRENT.tar.gz https://github.com/rakshasa/rtorrent/archive/$VER_RTORRENT.tar.gz &&     tar xzf rtorrent-$VER_RTORRENT.tar.gz &&     cd rtorrent-$VER_RTORRENT &&     ./autogen.sh &&     ./configure --with-xmlrpc-c --with-ncurses &&     make &&     make install &&     cd .. &&     rm -rf rtorrent-* &&     ldconfig &&     mkdir -p /usr/share/nginx/html &&     cd /usr/share/nginx/html &&     mkdir rutorrent &&     curl -L -O https://github.com/Novik/ruTorrent/archive/master.tar.gz &&     tar xzvf master.tar.gz -C rutorrent --strip-components 1 &&     rm -rf *.tar.gz &&     apt-get purge -y --auto-remove ${build_deps} &&     apt-get autoremove -y' returned a non-zero code: 2

Just replace the svn URL on line 24 in the Dockerfile:

bash
svn --trust-server-cert checkout https://svn.code.sf.net/p/xmlrpc-c/code/super_stable/ xmlrpc-c &&

Run the docktorrent build:

bash
docker build -t docktorrentuser1 .

After compiling, run docktorrentuser1:

bash
    docker run -it 
    -p 80:80 -p 45566:45566 -p 9527:9527/udp 
    --dns 8.8.8.8 
    -v /home/seedbox/user1:/rtorrent 
    -e UPLOAD_RATE=1024 
    --name docktorrentuser1 
    -d 
    docktorrentuser1

To add another user, you need to repeat the previous steps for our users:

bash
nano config/rtorrent/.rtorrent.rc

Change the credential pair for the new user2:

dockerfile
RUN htpasswd -cb /usr/share/nginx/html/rutorrent/.htpasswd user2 passworduser2

Rebuild with a new name:

bash
docker build -t docktorrentuser2 .

Run the docker for user2 on port 81 of our host by changing the ports:

bash
 docker run -it 
    -p 81:80 -p 45567:45566 -p 9528:9527/udp 
    --dns 8.8.8.8 
    -v /home/seedbox/user2:/rtorrent 
    -e UPLOAD_RATE=1024 
    --name docktorrentuser2 
    -d 
    docktorrentuser2

In my case, I mount the downloads folder into that of the users with the following command:

bash
mount --bind /home/seedbox/downloads/ /home/seedbox/user1/downloads

Running and configuring pms-docker

Download the project's image ( by default)

bash
docker pull plexinc/pms-docker

Info: There are several TAGs available on Plex's Docker image, such as: latest, public, plexpass

In my case, I've been a Plex Lifetime Premium member since 2013, so I use the tag: plexpass:

bash
docker pull plexinc/pms-docker:plexpas

The difference is that every time my Plex () container restarts, it will automatically update if a newer version is available. As for the "latest" version, it won't update, but the "public" version apparently does the same thing.

Run the Plex Docker as follows:

bash
docker run --name plex -p 32400:32400/tcp -e TZ="Europe/Paris" -e PLEX_CLAIM="claim-veFRSmSwMgpQEV1USsjE"-e -h plex.kassianoff.fr -v /home/seedbox/plex_config/:/config -v /home/seedbox/downloads/:/data plexinc/pms-docker:plexpass

Head to the following address: https://plex.tv/claim, since in the settings you need to remember that a token is required to authenticate your container:

PLEX_CLAIM="claim-veFRSmSwMgpQEV1USsjE"

To finalize the Plex Server's configuration, connect via SSH to the server following this example: "PMS" access without a graphical interface! I now invite you to check that your docker containers are working, like this:

bash
docker ps
bash
CONTAINER ID        IMAGE                          COMMAND                CREATED             STATUS              PORTS                                                                            NAMES
8afb950273f4        docktorrentuser1:latest   "/usr/local/bin/dock   2 days ago         Up 2 days          0.0.0.0:80->80/tcp, 0.0.0.0:9527->9527/udp, 9527/tcp, 0.0.0.0:45566->45566/tcp   docktorrentuser1
b6d9446d42d1        docktorrentuser2:latest   "/usr/local/bin/dock   2 days ago         Up 2 days          9527/tcp, 0.0.0.0:81->80/tcp, 0.0.0.0:9528->9527/udp, 0.0.0.0:45567->45566/tcp   docktorrentuser2
b94927f31cd4        plex:plexpass "/start.sh" 2 days ago Up 2 days 0.0.0.0:32400->32400/tcp plexseedbox

For better security, use a reverse proxy in front of your dockers, for example Pound.
Here's my configuration for two subdomains, user1 and user2, toward Docker's bridge interface:

bash
ListenHTTPS
        Address 62.XXX.XXX.XXX
        Port 443
        Cert "/etc/pound/ssl/www/user1.pem"
        Cert "/etc/pound/ssl/www/user2.pem"
        AddHeader "X-Forwarded-Proto: https"
        ## allow PUT and DELETE also (by default only GET, POST and HEAD)?:
        xHTTP           2
        Service
                HeadRequire "Host: .*user1.kassianoff.fr.*"
                BackEnd
                        Address 172.17.42.1
                        Port    80
                End
        End
        Service
                HeadRequire "Host: .*user2.kassianoff.fr.*"
                BackEnd
                        Address 172.17.42.1
                        Port 81
                End
        End
End

To generate a self-signed SSL certificate: http://doc.ubuntu-fr.org/tutoriel/comment_creer_un_certificat_ssl.

Success! You're now ready to share all of the moment's Linux distributions with your great seedbox and stream your family videos on Plex. Enjoy!

Conclusion

Docker here lets you quickly deploy a complete seedbox by combining the docktorrent (rTorrent/ruTorrent) and pms-docker (Plex Media Server) projects, without going through a long, tedious manual installation. This approach greatly simplifies migrating from one dedicated server to another, since all you need to do is rebuild the images and remount the data volumes. For security, adding a reverse proxy like Pound in front of the containers is recommended, especially to handle HTTPS and multi-user setups.