mirror of
https://github.com/EdyTheCow/docker-media-center.git
synced 2024-11-21 10:05:49 +02:00
Finish docs and configs
This commit is contained in:
parent
228fe7e224
commit
603c938ac1
81
README.md
81
README.md
@ -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
16
_base/compose/.env
Normal 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=
|
25
_base/compose/docker-compose.yml
Normal file
25
_base/compose/docker-compose.yml
Normal 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"
|
0
_base/data/traefik/.htpasswd
Normal file
0
_base/data/traefik/.htpasswd
Normal file
0
_base/data/traefik/acme.json
Normal file
0
_base/data/traefik/acme.json
Normal file
24
_base/data/traefik/traefik.toml
Normal file
24
_base/data/traefik/traefik.toml
Normal 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
26
dmc/compose/.env
Normal 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
|
152
dmc/compose/docker-compose.yml
Normal file
152
dmc/compose/docker-compose.yml
Normal 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
0
dmc/data/.gitkeep
Normal file
0
dmc/services/.gitkeep
Normal file
0
dmc/services/.gitkeep
Normal file
Loading…
Reference in New Issue
Block a user