Finish docs and configs

This commit is contained in:
EdyTheCow 2023-04-07 21:10:53 +00:00
parent 228fe7e224
commit 603c938ac1
10 changed files with 303 additions and 21 deletions

View File

@ -4,7 +4,9 @@
# 📚 About
Docker Media Center is a fully automated media set-up using Jellyfin and a bunch of other services to achieve full automation. All of the services listed below are running behind Traefik reverse proxy with proper certificates and basic auth. Most other similar set-up were either lacking some sort of reverse proxy and were rather exposing ports or were poorly documented. This guide aims for the quickest way to set-up a secure and production ready media center set-up.
Docker Media Center is a fully automated media set-up using Jellyfin and a bunch of other services to achieve full automation. All of the services listed below are running behind Traefik reverse proxy with proper certificates and basic auth. Most other similar setups were either lacking a reverse proxy and exposing ports or were poorly documented. This guide aims for the quickest way to set-up a secure and production ready media center.
Furthermore, the guide is set up with volume paths in a way to allow hardlinks of media files rather than making copies. This means once a media file is downloaded, it is hardlinked to the Jellyfin media directory rather than copied. Such a method is faster and saves storage on your server.
### Services
- Jellyfin
@ -15,7 +17,7 @@ Docker Media Center is a fully automated media set-up using Jellyfin and a bunch
- Jellyseerr
# 🧰 Getting Started
This guide assumes you have a basic knowledge of linux and Docker / Docker Compose.
This guide assumes you have a basic knowledge of linux and Docker / Docker Compose.
### Requirements
- Domain
@ -34,7 +36,8 @@ Navigate to `dmc/compose/.env/` and edit these variables.
|---|---|---|
| COMPOSE_PROJECT_NAME | dmc | The prefix for all of containers when started from the compose file |
| DOMAIN | domain.com | The domain that's going to be used to access Jellyfin and rest of the other services |
| DATA_DIR | ../data | The location where all of configs, media and downloads are going to be stored. By default it's stored in the data folder |
| DATA_DIR | ../data | The location where all of media and downloads are going to be stored |
| SERVICES_DIR | ../data | The location where all of services configs are stored |
| TIMEZONE | Europe/Oslo | Your timezone, you can find all of the valid timezones here: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List |
| ENV_PUID | 1000 | Your user ID, used for file permissions. You can find it by running command: id |
| ENV_PGUID | 1000 | Your group ID, used for file permissions. You can find it by running command: id | |
@ -57,7 +60,7 @@ If you're using Cloudflare, make sure to enable the proxying by enabling the clo
| sonarr.domain.com | CNAME | dmc.domain.com |
| prowlarr.domain.com | CNAME | dmc.domain.com |
## Setting up Traefik
## Traefik
<b>Clone repository</b><br />
```
git clone https://github.com/EdyTheCow/docker-media-center.git
@ -71,7 +74,7 @@ sudo chmod 600 acme.json
```
<b>Basic auth</b><br />
Navigate to `_base/data/traefik/.htpasswd` and paste your generated user/pass in MD5 format. This will be your basic auth user/pass for most services we're going to set up.
Navigate to `_base/data/traefik/.htpasswd` and paste your generated user/pass in MD5 format. This will be your basic auth user/pass for most services we're going to set up. If unsure, google how to generate htpasswd.
<b>Start docker compose</b><br />
Inside of `_base/compose` run
@ -89,48 +92,84 @@ Navigate to `jellyfin.domain.com` in your browser and follow the instructions. W
| Library | Path |
|---|---|
| Movies | /data/media/local/movies |
| TV Shows | /data/media/local/tvshows |
| Movies | /data/media/movies |
| TV Shows | /data/media/tvshows |
Jellyfin only has one volume pointing at `/data/media` this allows us to add whatever media type we want without having to define extra volumes in docker. The reason why it's under `local` directory is in case we wanted to mount google drive or similar in the future, we could add media under `gdrive` instead of `local` for example.
Jellyfin only has one volume pointing at `/data/media` this allows us to add whatever media type we want without having to define extra volumes in docker for future media types.
## Transmission
Start service
Inside of `dmc/compose` run
```
docker-compose up -d transmission
```
<b>Configuration</b><br />
Navigate to `transmission.domain.com` in your browser, you should be asked to login using the credentials for basic auth you set-up earlier. Make sure everything works, other than that there's no further configuration.
## Prowlarr
Navigate to `transmission.domain.com` in your browser, you should be asked to login using the credentials for basic auth you set-up earlier. Under `Preferences -> Torrents` make sure your download paths look like this: `/data/downloads/complete` and `/data/downloads/incomplete`. This will be important later on for hardlinks.
## Radarr
Start service
Inside of `dmc/compose` run
```
docker-compose up -d radarr
```
<b>Configuration</b><br />
Navigate to `radarr.domain.com` in your browser, in the panel under `Media Management` section and add the root folder by simply selecting `/data/media/movies` directory.
<b>Configuration</b><br />
In the panel, navigate to `Media Management` section and add root folder by simply selecting `/movies` directory.
Under `Download Clients` add a new client by selecting Transmission. Change these settings:
| Setting | Value |
|---|---|
| Name | Transmission |
| Host | transmission |
| Category | movies |
Host `transmission` will resolve the local IP of the container, do not use a domain or public IP. It's more convenient and secure to connect services locally. Since the connection is local, you do not need to insert any other credentials. Click `Test` to make sure it works and add the client.
## Sonarr
Start service
Inside of `dmc/compose` run
```
docker-compose up -d sonarr
```
<b>Configuration</b><br />
In the panel, navigate to `Media Management` section and add root folder by simply selecting `/tv` directory.
Navigate to `sonarr.domain.com` in your browser, in the panel under `Media Management` section and add the root folder by simply selecting `/data/media/tvshows` directory.
Under `Download Clients` add new client by selecting Transmission. Change these settings:
| Setting | Value |
|---|---|
| Name | Transmission |
| Host | transmission |
| Category | tvshows |
Host `transmission` will resolve the local IP of the container, do not use a domain or public IP. It's more convenient and secure to connect services locally. Since the connection is local, you do not need to insert any other credentials. Click `Test` to make sure it works and add the client.
## Prowlarr
Inside of `dmc/compose` run
```
docker-compose up -d prowlarr
```
<b>Configuration</b><br />
Navigate to `prowlarr.domain.com` in your browser, under `Settings -> Apps` add Sonarr and Radarr.
| Setting | Value |
|---|---|
| Name | Radarr |
| Sync Level | Full Sync |
| Prowlarr Server | http://prowlarr:9696 |
| Radarr Server | http://radarr:7878 |
Instructions for adding Sonarr are exactly the same, just change the name to `Sonarr` and use `http://sonarr:8989` for `Sonarr Server`. You'll find API keys for both under `Settings -> General` in their respective panels.
Navigate to `Indexers` and click `Add Indexer` to add public or private indexers. Once added, these will automatically sync with Sonarr and Radarr.
## Jellyseerr
Start service
Inside of `dmc/compose` run
```
docker-compose up -d jellyseerr
```
<b>Configuration</b><br />
Select option to use `Jellyfin account` and proceed by providing url and account details for your jellyfin installation. Scan and enable libraries.
Navigate to `jellyseerr.domain.com` in your browser, select option to use `Jellyfin account` and proceed by providing url and account details for your jellyfin installation. Scan and enable libraries.
<b>Adding radarr / sonarr</b><br />
Most importantly, do not use the actual url or IP of radarr / sonarr. Simply use `radarr` or `sonarr` for the hostname. This will resolve the local IP of the container rather than the public one. Since we're running everything on the same server, it's more secure and convenient to connect these services locally. Make sure to uncheck `Use SSL` option too for the local connection to work.
@ -140,10 +179,10 @@ Below are the important settings you should edit, the instructions for sonarr ar
| Setting | Value |
|---|---|
| Default Server | Checked |
| Server Name | Radarr (can be something else too) |
| Server Name | Radarr |
| Hostname or IP Address | radarr |
| Use SSL | Unchecked |
| API Key | Can be found under General section in radarr panel |
| API Key | Can be found under General section in radarr / sonarr panel |
# 📋 TODO

16
_base/compose/.env Normal file
View File

@ -0,0 +1,16 @@
##
# General Variables
##
COMPOSE_PROJECT_NAME=base
DATA_DIR=../data
##
# Container: traefik -- Traefik variables
##
## Only used if Cloudflare is selected in labels
# Cloudflare account email
CF_API_EMAIL=
# Cloudflare global api key
CF_API_KEY=

View File

@ -0,0 +1,25 @@
version: '3.7'
networks:
global:
external: true
services:
traefik:
image: traefik:v2.9
env_file:
- .env
networks:
- global
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ${DATA_DIR}/traefik/traefik.toml:/etc/traefik/traefik.toml
- ${DATA_DIR}/traefik/acme.json:/acme.json
- ${DATA_DIR}/traefik/.htpasswd:/.htpasswd
labels:
- "traefik.http.middlewares.dmc-auth.basicauth.usersfile=/.htpasswd"

View File

View File

View File

@ -0,0 +1,24 @@
[global]
checkNewVersion = false
sendAnonymousUsage = false
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.websecure]
address = ":443"
[providers.docker]
[certificatesResolvers.cloudflare.acme]
email = "admin@domain.com"
[certificatesResolvers.cloudflare.acme.dnsChallenge]
provider = "cloudflare"
delayBeforeCheck = 0
[certificatesResolvers.letsencrypt.acme]
email = "admin@domain.com"
storage = "acme.json"
[certificatesResolvers.letsencrypt.acme.httpChallenge]
entryPoint = "web"

26
dmc/compose/.env Normal file
View File

@ -0,0 +1,26 @@
# Containers prefix
COMPOSE_PROJECT_NAME=dmc
# Data location for storing media, downloads and configs
DATA_DIR=../data
SERVICES_DIR=../services
# Timezone
TIMEZONE=Europe/Oslo
# Linux user/group ID for file permissions
## User ID
ENV_PUID=1000
## Group ID
ENV_PGID=1000
# Domain
DOMAIN=domain.com
# Subdomains for accessing services
SUB_DOMAIN_JELLYFIN=jellyfin
SUB_DOMAIN_TRANSMISSION=transmission
SUB_DOMAIN_SONARR=sonarr
SUB_DOMAIN_RADARR=radarr
SUB_DOMAIN_PROWLARR=prowlarr
SUB_DOMAIN_JELLYSEERR=jellyseerr

View File

@ -0,0 +1,152 @@
version: "3.7"
networks:
global:
external: true
local:
external: false
services:
jellyfin:
image: lscr.io/linuxserver/jellyfin:latest
restart: unless-stopped
#security_opt: # Required for Docker versions below 20.10.10, update Docker for long term solution. Source: https://docs.linuxserver.io/faq#jammy
# - seccomp=unconfined
networks:
- global
- local
environment:
- PUID=${ENV_PUID}
- PGID=${ENV_PGID}
- TZ=${TIMEZONE}
volumes:
- ${SERVICES_DIR}/jellyfin:/config
- ${DATA_DIR}/media:/data/media
labels:
- "traefik.enable=true"
- "traefik.http.routers.dmc-jellyfin.rule=Host(`${SUB_DOMAIN_JELLYFIN}.${DOMAIN}`)"
- "traefik.http.routers.dmc-jellyfin.tls=true"
- "traefik.http.services.dmc-jellyfin.loadbalancer.server.port=8096"
- "traefik.http.routers.dmc-jellyfin.tls.certresolver=letsencrypt"
- "traefik.docker.network=global"
transmission:
image: lscr.io/linuxserver/transmission:latest
restart: unless-stopped
networks:
- global
- local
environment:
- PUID=${ENV_PUID}
- PGID=${ENV_PGID}
- TZ={TIMEZONE}
volumes:
- ${SERVICES_DIR}/transmission:/config
- ${DATA_DIR}/downloads:/data/downloads
ports:
- 51413:51413 # Torrent port TCP
- 51413:51413/udp # Torrent port UDP
labels:
- "traefik.enable=true"
- "traefik.http.routers.dmc-transmission.rule=Host(`${SUB_DOMAIN_TRANSMISSION}.${DOMAIN}`)"
- "traefik.http.routers.dmc-transmission.tls=true"
- "traefik.http.services.dmc-transmission.loadbalancer.server.port=9091"
- "traefik.http.routers.dmc-transmission.tls.certresolver=letsencrypt"
- "traefik.docker.network=global"
# Basic auth
- "traefik.http.middlewares.dmc-auth.basicauth.usersfile=/.htpasswd"
- "traefik.http.routers.dmc-transmission.middlewares=dmc-auth"
radarr:
image: lscr.io/linuxserver/radarr:latest
restart: unless-stopped
networks:
- global
- local
environment:
- PUID=${ENV_PUID}
- PGID=${ENV_PGID}
- TZ={TIMEZONE}
volumes:
- ${SERVICES_DIR}/radarr:/config
- ${DATA_DIR}:/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.dmc-radarr.rule=Host(`${SUB_DOMAIN_RADARR}.${DOMAIN}`)"
- "traefik.http.routers.dmc-radarr.tls=true"
- "traefik.http.services.dmc-radarr.loadbalancer.server.port=7878"
- "traefik.http.routers.dmc-radarr.tls.certresolver=letsencrypt"
- "traefik.docker.network=global"
# Basic auth
- "traefik.http.middlewares.dmc-auth.basicauth.usersfile=/.htpasswd"
- "traefik.http.routers.dmc-radarr.middlewares=dmc-auth"
sonarr:
image: lscr.io/linuxserver/sonarr:latest
restart: unless-stopped
#security_opt: # Required for Docker versions below 20.10.10, update Docker for long term solution. Source: https://docs.linuxserver.io/faq#jammy
# - seccomp=unconfined
networks:
- global
- local
environment:
- PUID=${ENV_PUID}
- PGID=${ENV_PGID}
- TZ={TIMEZONE}
volumes:
- ${SERVICES_DIR}/sonarr:/config
- ${DATA_DIR}:/data
labels:
- "traefik.enable=true"
- "traefik.http.routers.dmc-sonarr.rule=Host(`${SUB_DOMAIN_SONARR}.${DOMAIN}`)"
- "traefik.http.routers.dmc-sonarr.tls=true"
- "traefik.http.services.dmc-sonarr.loadbalancer.server.port=8989"
- "traefik.http.routers.dmc-sonarr.tls.certresolver=letsencrypt"
- "traefik.docker.network=global"
# Basic auth
- "traefik.http.middlewares.dmc-auth.basicauth.usersfile=/.htpasswd"
- "traefik.http.routers.dmc-sonarr.middlewares=dmc-auth"
prowlarr:
image: lscr.io/linuxserver/prowlarr:latest
restart: unless-stopped
networks:
- global
- local
environment:
- PUID=${ENV_PUID}
- PGID=${ENV_PGID}
- TZ={TIMEZONE}
volumes:
- ${SERVICES_DIR}/prowlarr:/config
labels:
- "traefik.enable=true"
- "traefik.http.routers.dmc-prowlarr.rule=Host(`${SUB_DOMAIN_PROWLARR}.${DOMAIN}`)"
- "traefik.http.routers.dmc-prowlarr.tls=true"
- "traefik.http.services.dmc-prowlarr.loadbalancer.server.port=9696"
- "traefik.http.routers.dmc-prowlarr.tls.certresolver=letsencrypt"
- "traefik.docker.network=global"
# Basic auth
- "traefik.http.middlewares.dmc-auth.basicauth.usersfile=/.htpasswd"
- "traefik.http.routers.dmc-prowlarr.middlewares=dmc-auth"
jellyseerr:
image: fallenbagel/jellyseerr:latest
restart: unless-stopped
networks:
- global
- local
environment:
- LOG_LEVEL=debug
- TZ={TIMEZONE}
volumes:
- ${SERVICES_DIR}/jellyseerr:/app/config
labels:
- "traefik.enable=true"
- "traefik.http.routers.dmc-jellyseerr.rule=Host(`${SUB_DOMAIN_JELLYSEERR}.${DOMAIN}`)"
- "traefik.http.routers.dmc-jellyseerr.tls=true"
- "traefik.http.services.dmc-jellyseerr.loadbalancer.server.port=5055"
- "traefik.http.routers.dmc-jellyseerr.tls.certresolver=letsencrypt"
- "traefik.docker.network=global"

0
dmc/data/.gitkeep Normal file
View File

0
dmc/services/.gitkeep Normal file
View File