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 theuid
andgid
respectivelyPUID
andPGID
for the.env
.
- once it’s done, connect on SSH and type
Connect on SSH and download
docker-compose
latest command version:- or use my custom script to download the latest docker-compose release
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)
Service | Address |
---|---|
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/Service | Internal Port | External Port | Protocol | Equipment |
---|---|---|---|---|
HTTP | 8080 | 80 | TCP/UDP | Your-Server |
HTTPS | 4443 | 443 | TCP/UDP | Your-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
andyourdomain.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
- Media Management:
- check
Replace Illegal Characters
- Colon Replacement:
Delete
- Path
/downloads/medias/movies
(for sonarr:/downloads/medias/series
)
- check
- Profiles : click on your profile and
Edit groups
, then ungroup your selected qualities - Quality: Not changed
- Custom Formats: automatically imported with recyclarr
- Indexer: it’ll be added automatically with Prowlarr
- 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):
- Tailscale on Synology
- CloudFlare Tunnel
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:
- Modify the jellyhookapi.py file:
You'll need to customize the JellyHookAPI/jellyhookapi.py file according to your specific needs. - Add the Handlebars template:
Navigate to Jellyfin > Plugin > Webhook > "Generic Destination" and add the Handlebars template. - 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":
- if you want to receive notification when a new item (movie/tv show/...) is added, check "Item Added"
- or when a user is locked out (because of too much wrong password during connection), check "User Locked Out"
- 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)
- webhooks/jellyfin/discord/discord-item.handlebars
- webhooks/jellyfin/discord/discord-users-locked-out.handlebars
- 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:
- click on "Add a Generic Destination"
- check the steps for Discord, it's the same
- "Template":
- "Item Added": webhooks/jellyfin/ms-teams/teams-items.handlebars
- "User Locked Out": webhooks/jellyfin/ms-teams/teams-users-locked-out.handlebars
- "User": webhooks/jellyfin/ms-teams/teams-users.handlebars
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 theratio
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.