A built in VPN container, through which all other containers’ traffic is routed
Plex: A media library management tool that organizes and streams your media files.”
Tautulli: Companion software to Plex, fine-grained control for monitoring and managing your streams
Sonarr, Radarr, Lidarr, Bazarr: Automating the downloads of TV shows, movies, music, and subtitles (in that order)
Jackett: API-based management of indexers for the aforementioned list of download clients
QBittorrent: Torrent client
Watchtower: Tool to auto-update the containers
If you’re here, you’ve probably heard the famous words from Valve’s founder:
Piracy is an issue of service, not price.
– Gabe Newell
Since I myself can’t stand technical articles that explore philosophy before going to the technical parts, I’ll leave it at that, and jump into the technical breakdown on the whats and hows. If even that is too much for you, you can jump to the end for the yamls.
I obviously don’t advocate doing anything illegal. This tutorial is entirely theoretical, and no law abiding citizen should have something like this running in their closet, supplying them with and endless stream of entertainment media. Absolutely not.
Piracy is bad, mmkay?
A small breakdown of the skills, tools, & technologies that are needed to use this:
Server: I strongly suggest setting this up on a dedicated server. The hardware requirements are relatively low (I used to run this on an old laptop before upgrading), but once you get into heavy transcoding you might want to upgrade.
Storage: While not strictly necessary, I can with absolute certainty say that you will end up needing lots and lots of storage. I’m currently up to 40TB, and it’s starting to run out.
Operating system: Not a strict requirement, but I strongly suggest using Linux. Docker on windows uses a self-managed Linux VM anyways. + Everything I mention runs in a Linux environment for me, and I haven’t tested the setup on Windows, so I won’t be able to definitively answer questions or troubleshoot on Windows.
Docker: docker must be installed and configured to be used with docker compose. Obviously, since this is a tutorial for setting this up with docker compose.
Docker Compose: see above.
CLI: I strongly advise being at least somewhat comfortable using a CLI – You won’t be working with it too much in the scope of this tutorial, but you shouldn’t be scared of it.
Docker: You should know at least the basics of what containers are, how they work, how they communicate with each other, and most importantly, how volumes work.
Networking: you’ll need a basic understanding of what a VPN is, how port forwarding works, how to access services on your network, how p2p file sharing works. Advanced knowledge is recommended if you want to do deeper configs – VPN chaining, putting the services behind a reverse proxy etc.
An outline of the setup
Sonarr/Radarr/Lidarr monitor the release of media, bazarr downloads subtitles for newly downloaded series and movies.
Once something is released, it polls the indexers/trackers configured in Jackett.
Jackett gives back a list of torrents to the programs, which pick the one most fitting for your configured profile (quality+filesize+release type).
Sonarr/Radarr/Lidarr forward the torrent to QBittorent, which then downloads the media.
Sonarr/Radarr/Lidarr monitor the download, and once it’s done, imports it into the specified media folders.
Plex monitors the media folders, and automatically picks up the newly downloaded media. It sorts it into your libraries, downloads metadata for it, and provides your own streaming platform for it. Think of it as your private netflix.
Anything that happens on Plex, Tautulli keeps track of it
All the while Watchtower runs in the background, periodically checking for updates to the container images.
The tools are pretty amazing: they automatically monitor the feeds you configure, and pull new movies/songs/episodes once they’re released without you needing to check up on them. They even provide a calendar for the release dates, so whenever you’re feeling impatient you can check when something will be available.
You’re okay with a 4k BDRip needing 20GB, but you don’t want a 720p WEBRip to take up the same space? You’re okay with old cartoons being DVD quality, but want all new shows to be at least 1080p? No problem, you can configure detailed qulity profiles, including release type, acceptable file size range, and quality, with ranked preferences.
Plex then automatically pulls a slew of metadata for all your media and keeps even astoundingly large libraries organized. If you want to share it with family, tautulli will help you keep a tight grip on your resources: you can kill resource hogging paused streams, limit transcoding options, get advanced statistics, send a plethora of notifications (including when new media is added!) through scripts, webhooks and chatbots, and a lot more, especially if you integrate things like JBOPS.
First thing’s first: you should keep your media and configs organized. It’ll save you a lot of headaches later on. I suggest a directory structure similar to this:
The directories under media will be shared between the containers, and each container will have a dedicated config directory. This makes troubleshooting as well as backing your data up significantly easier – I’ve migrated my install between multiple servers by now, and all it took each time was to 1:1 shift the config directories between the machines and restart the stack.
Next up are the containers.
In my opinion, the most curcial part of the setup is the VPN; if you use the right one, you can hide your activity behind it (at least well enough that you won’t be bugged by your ISP.)
I use NordVPN, but I’m in no ways trying to endorse it or advocate for it. I strongly suggest you look into what works best for you.
After trying out many, many different VPN images that worked with varying success, I’ve decided to build my own. It’s simple, it’s provider-agnostic, and you can read more details on github.
The start of your docker-compose.yml should look like this:
These are the default ports for the applications that you will use. If you want to change the port on the host, you can simply change the port on the left side of the mappings. If you want to change the application ports, you’ll need to look up how to do it in the documentation of the docker images, and change the right side as well.
The LOCAL_NETWORK variable should be set to your local network CIDR, you can get this from your router. If you want to do things like VPN chaining you can also use your VPN’s subnet. Support for more networks in my container is incoming, but is not a priority as of now.
The config directory on your host machine should have at least one (or more) .ovpn files in it for your VPN connection.
There are two very important features used here: the depends_on and network_mode keys.
The network_mode: service: vpn set here will tunnel your traffic through the VPN container, and is also the reason why the ports are mapped on the VPN container, and not here. This can cause some conflicts (e.g. if a port is used by more than one container) and there are other ways to do it, but for the purpose of this tutorial this is a perfectly funcitonal solution.
A very important note here: qbittorrent’s default setting binds to any available network device. When you create the VPN, a new virtual device will be created, most likely called tun0. Your VPN connection will be ran through this device. If you leave qBittorrent’s setting as default, it might use your non-vpn connection to download. To avoid leaking your IP like this, make sure to go into Tools > Options > Advanced and set your network interface to tun0. DO NOT SKIP THIS.
The depends_on key first and foremost makes sure that the VPN container is already running before the other containers are started. I’ve also jackett and qbittorrent for the release managers, since they poll the services upon container start, and will complain if they’re unreachable at the time.
For plex and tautulli, I use a separate stack. Tautulli is harmless, and my plex installation is ran through the official platform of plex itself, is reachable on app.plex.tv, and is only shared with my family, so I felt that putting it behind a VPN would only be a drag on network speed for relatively low added security. You can, however, still choose to put it behind your VPN by adding them to the stack above, mapping their ports, and setting their network_mode.