caution

Disclaimer: The author and contributors do not claim ownership of any services listed or used in this repository and are not legally responsible for any improper or illegal use. It is provided for educational purposes only. The repository does not endorse piracy or copyright infringement. Creating a media platform based on torrents may involve downloading copyrighted content, which, without proper authorization, may be illegal in many jurisdictions. All rights go to the owners of the software used.

About

In this very complete guide (available here on github), you’ll be able to install from scratch a perfect home-server for a full media donwload and stream automation

This is my perfect docker-compose for my streaming server.

You’ll find two 2 docker-compose, one to create the streaming services and the other one to access them through a reverse proxy.

note

I’ve also created a chill-extra folder that automatically sends notifications on WhatsApp as soon as media is added in Jellyfin, add the removarr docker and other scripts.

important

The only thing to modify is the .env file to suits your setup.

Here, we are going to install everything under /opt/chill/ (full streaming automation) and /opt/docker/ (reverse proxy).

To install everything, just follow this Readme in this order.

Requirements

  • docker
  • docker-compose
  • a server maybe? I deployed these docker-compose on 2 servers: a Synology DS923+ and a custom server
  • create docker user

Synology Server:

  • Download the Docker App available on Synology Package Center

  • Create a docker user

    • once it’s done, connect on SSH and type id <username> and write down the uid and gid respectively PUID and PGID for the .env.
  • Connect on SSH and download docker-compose latest command version:

  • check version: $ docker-compose version

Medias Server

What’s inside

This docker-compose contains:

Installation

  • Delete previous installation be careful
$ rm -rf /opt/chill
  • Create the structure for every services
$ mkdir -p /opt/chill/{{jellyfin,jellyseerr,prowlarr,radarr,sonarr,transovpn}/config,storage/downloads/{watch,completed,incomplete,medias/{movies,series}}}

Here is what it’s going to create:

opt
└── chill
    ├── jellyfin
    │   └── config
    ├── jellyseerr
    │   └── config
    ├── prowlarr
    │   └── config
    ├── radarr
    │   └── config
    ├── sonarr
    │   └── config
    ├── storage
    │   └── downloads
    │       ├── completed
    │       ├── incomplete
    │       ├── medias
    │       │   ├── movies
    │       │   └── series
    │       └── watch
    └── transovpn
        └── config

The /opt/chill/storage/downloads/watch/ folder is used when you manually put .torrent files, so it’s going to be downloaded automatically without any access to the Transmission interface.

  • To check everything was properly created
$ ls -lR /opt/chill

Download the docker-compose-medias.yml and .env-example in /opt/chill/, and rename them:

$ cd /opt/chill
$ wget https://raw.githubusercontent.com/garnajee/home-server/master/docker-compose-medias.yml -O docker-compose.yml
$ wget https://raw.githubusercontent.com/garnajee/home-server/master/.env-example -O .env

Modify .env

Normally, you don’t need to modify the docker-compose.yml file. Only the .env file.

  • list of VPN PROVIDERS
  • local subnet mask for NETWORKIP (use this command to know yours) : ip route | awk '!/ (docker0|br-)/ && /src/ {print $1}'
  • PUID and PGID
  • TZ

Create a docker network

This part is optional. It’s going to be created automatically. But you can still do it manually if you want.

I did it manually because of the reverse proxy causing errors if I attached it to the automatically created docker subnet.

All these images are going to be in the same docker network. To avoid any further conflict, just create it before running the docker-compose.

Here the subnet is 10.10.66.0/24. If you want to change this by something else, you’ll need to modify the docker-compose.yml too. But remember, it’s just a subnet inside docker, it’s not going to affect your local network.

$ docker network rm net-chill
$ docker network create net-chill -d bridge --subnet 10.10.66.0/24

Run!

For the first execution of the docker-compose, I recommend to use this command, to check if there is no errors:

Move the docker-compose.yml and .env file in /opt/chill/.

$ cd /opt/chill/
$ docker-compose up

It’s going to download all the images, and start all the services.

By the way, each request made by Prowlarr and FlareSolverr goes through the VPN.

Now, if you don’t see any red lines among the hundreds of lines that have just scrolled through the terminal, it’s usually a good sign.

So you can now stop this by pressing CTRL+c (one or two times to force stop), and then run the docker-compose again, but in background this time:

$ cd /opt/chill/
$ docker-compose up -d

Check the status of each docker:

$ docker-compose ps -a

Status should be Up.

Check VPN connection

Now everything is up, just to be sure, you can check if Transmission goes through VPN:

$ docker exec -it transovpn curl ifconfig.co
XXX.XXX.XXX.XXX

And then check the location of this ip address here for example.

You can do the same command (just to be sure) for Prowlarr and Flaresolverr, they have the same ip address.

Update docker’s images

Update one specific image

To update one specific docker image:

$ cd /opt/chill
$ docker-compose stop <container_name>
$ docker-compose rm <container_name>
$ docker-compose pull <container_name>
$ docker-compose up -d

Update all images

To update all images:

$ docker-compose down
$ docker-compose pull
$ docker-compose up -d

Access services

To access services: (IP is the ip of your server)

ServiceAddress
Transmission-openvpn<IP>:8000
Prowlarr<IP>:8001
FlareSolverr<IP>:8002
Jellyfin<IP>:8003
Jellyseerr<IP>:8004
Radarr<IP>:8010
Sonarr<IP>:8011

Reverse Proxy

To access Jellyfin and Jellyseerr from outside your local network, you’ll need to set up a reverse proxy.

For that purpose, I’m going to use Nginx Proxy Manager.

You also need to open 2 ports on your router:

Application/ServiceInternal PortExternal PortProtocolEquipment
HTTP808080TCP/UDPYour-Server
HTTPS4443443TCP/UDPYour-Server

What’s inside

This docker-compose contains:

Installation

  • Create the directory structure
$ mkdir -p /opt/docker/{nginx-proxy-manager,npm-db}

Download the docker-compose-rp.yml in /opt/docker/, and rename it:

$ cd /opt/docker
$ wget https://raw.githubusercontent.com/garnajee/home-server/master/docker-compose-rp.yml -O docker-compose.yml

I didn’t create a .env file for this docker-compose mainly as this service is not going to be exposed on the web.

Feel free to modify user, password, name, and so on directly in the docker-compose.yml.

Run

Simply execute this:

$ cd /opt/docker/
$ docker-compose up

Again, it’s going to download the docker images. Check if there is no error, and if it’s good, hit CTRL+c to stop everything and run this command:

$ docker-compose up -d

The service will be accessible at: <IP>:81.

The default Admin User is:

email: admin@example.com
password: changeme

You’ll be ask to change these informations after the first logging.

Get a domain name & SSL certificate

I bought a domain name from OVH. If you do the same, follow this:

  • create an account on OVH
  • buy a domain name
  • once your domain name has been activated, create the necessary token for SSL
  • use this link
  • Make sure to write everything

You’ll need something like this:

dns_ovh_endpoint = ovh-eu
dns_ovh_application_key = 109XXX7595XXXXXa
dns_ovh_application_secret = a1z2g3y435TGcazbXXXXXXXXa45e
dns_ovh_consumer_key = agf6hU1g13uj86XXXXXXXXXfv1l2n3g4j
  • To create your certificate, go back on NPM (<IP>:81), “SSL Certificates” tab, “Add …”
  • fill the information for: *.yourdomain.com and yourdomain.com

Setup all the services

Transmission-openvpn

Nothing to setup or maybe the “Speed Limits” depending on your internet connection.

Radarr & Sonarr

Follow these guides.

I create a config to prefer download WEB-DL - MULTi (Original language + Truefrench) - 1080p - h264 - and NO HDR/10 bit.

If you want to have the same config, see the recyclarr-setup folder.

Radarr/Sonarr Settings

  1. Media Management:
    • check Replace Illegal Characters
    • Colon Replacement: Delete
    • Path /downloads/medias/movies (for sonarr: /downloads/medias/series)
  2. Profiles : click on your profile and Edit groups, then ungroup your selected qualities
  3. Quality: Not changed
  4. Custom Formats: automatically imported with recyclarr
  5. Indexer: it’ll be added automatically with Prowlarr
  6. Download Client:
    • add transmission
    • host: 10.10.66.100
    • port: 9091
    • set username and password
    • recent priority: last
    • older priority: last
    • check Remove Completed
    • Remote Path Mappings: Host: 10.10.66.100 (Transmission) ; Remote Path: /data/completed/ ; Local Path: /downloads/completed/

important

Go under settings/general and copy the API key, you’ll need it for Prowlarr

Prowlarr

Add your indexer. In Tags field, add “flaresolverr”.

In order to add Flaresolverr proxy:

  • go to Settings > Indexers
  • add “Flaresolverr”
  • make sure the tag is “flaresolverr”
  • add this ip address: “http://10.10.66.100:8191”
  • save

Connect to Radarr/Sonarr:

  • go to Settings > Apps
  • add radarr:
    • full sync
    • prowlarr server: http://10.10.66.100:9696
    • radarr server: http://10.10.66.110:7878

Jellyfin

Follow the steps, it’s easy.

Create all the users who are going to access to Jellyfin and Jellyseerr.

To have better images for your libraries, you can use these images.

Prevent users from changing their password:

Go into Dashboard > General > scroll down to the CSS section and add this CSS code:

.updatePasswordForm {
  display: none !important;
}

Add a custom button in the menu

You can add a custom button to the Jellyfin menu. For example, you can add a link to Jellyseerr.

To do that, you need to add this line in the Jellyfin’s volume field in the docker-compose file:

- ${BASE}/jellyfin/web-config.json:/usr/share/jellyfin/web/config.json

And add the web-config.json file in your /opt/chill/jellyfin/ folder.

You’ll see that the docker path is not the same as in the documentation. I don’t know why, but that’s the only way I can get it to work.

Read more here.

Jellyseerr

Follow the steps, it’s easy.

Sign in with your Jellyfin account and make sure to use the jellyfin internal docker ip address for the “Jellyfin URL”.

When Syncing Librairies, uncheck “Collections”.

Then, add your radarr and sonarr server (still with the internal docker ip address).

Once this is done, you can sync Jellyfin users with Jellyseerr, so that they have the same account for Jellyfin and Jellyseerr.

For sonarr server settings, make sure to check Season folder.

Bonus

Don’t want to use a reverse proxy?

You can use a VPN:

  • Official Synology VPN package -> need to open port on your router

And if you don’t want to open port on your router (or if you can’t):

warning

Pay attention to not use CloudFlare tunnel for Jellyfin streaming, you may be banned for breaking TOS.

Webhooks

I provide some webhooks for Jellyfin. These webhooks are used for:

First of all, you need to install the Jellyfin plugin called “Webhooks”: Jellyfin > Dashboard > Plugins > Catalog > Webhook

Then, you need to restart Jellyfin:

$ cd /opt/chill/
$ docker-compose restart jellyfin

Now, go back to Jellyfin in the Plugins tab and click on Webhook.

The “Server Url” is your Jellyfin URL. If you expose it on internet, it’s something like this: https://jellyfin.yourdomainname.com/

If you don’t have a domain name, Jellyfin will not be able to display images (posters) in the Discord/Teams webhooks.

Any API

This method will allow you to send a webhook to any service/api you want in a very easy way.

This consists of using your own API and create your request in Python (which is more flexible than the Jellyfin Webhook plugin) and send it to the API you want.

Steps:
  1. Modify the jellyhookapi.py file:
    You'll need to customize the JellyHookAPI/jellyhookapi.py file according to your specific needs.
  2. Add the Handlebars template:
    Navigate to Jellyfin > Plugin > Webhook > "Generic Destination" and add the Handlebars template.
  3. Build and run the Docker image:
    For detailed instructions on building and running the Docker image, refer to the JellyHookAPI/README in the JellyHookAPI folder.

Finally, in my case, I wanted to send notification to a WhatsApp group. If you wan to do this, follow these instructions

Discord Webhook

To add a Discord webhook:

  • click on "Add Discord Destination"
  • "Webhook Name": what you want
  • "Webhook Url": the discord webhook url
  • "Notification type":
    1. if you want to receive notification when a new item (movie/tv show/...) is added, check "Item Added"
    2. or when a user is locked out (because of too much wrong password during connection), check "User Locked Out"
    3. or when a user is created/deleted, when a password is changed, ... (for every use case check this file), check "Authentication" and "User"
  • "User Filter": personally, I don't check anything here
  • "Item Type": check everything (depending on your webhook template) except "Send All Properties"
  • "Template": (copy and paste the content)
    1. webhooks/jellyfin/discord/discord-item.handlebars
    2. webhooks/jellyfin/discord/discord-users-locked-out.handlebars
    3. webhooks/jellyfin/discord/discord-users.handlebars
  • "Avatar Url": just change the avatar profile picture directly on Discord
  • "Webhook Username": should not be empty, but you can write what you want, the real username is defined directly in Discord
  • "Mention Type": I never used this
  • "Embed Color": color of the embedded message

Then click save.

Microsoft Teams Webhook

To add a Microsoft Teams webhook:

Fake Ratio

If you need to fake your upload stats on (semi-)private indexers, in order to have a ratio >= 1.

caution

I don’t recommend using this indefinitely, please consider sharing to the community.

You can use Ratio.py.

To use this python script in a secure way, you can add it in the transmission-openvpn docker (already running). That way, everything will go through the vpn.

To do this, follow these steps:
  • create the folder:
$ cd /opt/chill
$ mkdir -p transovpn/ratio
  • add this in the docker-compose.yml:
volumes:
  - ${BASE}/transovpn/config:/config
  - ${DOWNLOADS}:/data
  - ${BASE}/transovpn/ratio/:/home/
  • then download the content of Ratio.py repository inside the ratio folder.
  • download a very popular and highly leeched torrent file and put it inside the ratio folder.
  • modify the config.json file to match the torrent file name and path. Add your desired upload speed.
  • install python and run the script:
$ cd /opt/chill/
$ docker exec -it transovpn bash
# apt update && apt install python3 python3-pip
# cd /home
# pip install -r requirements.txt
# nohup python3 ratio.py -c config.json &
  • to view logs : # tail -f nohup.out

License

This project is under MIT License.