May 31, 2018

Docker-based HTPC set-up

This is a quick run through for setting up a HTPC (Home Theatre PC). It requires a docker installation, which is available for most modern Operating systems (official installation instructions). These instructions were completed with linux so it may not work 100% "as-is" for other operating systems. It will use the following components:


One thing to note is that I use a separate docker network to isolate all my services from the default bridge network. You can create your own using: docker network create traefik



No-IP for Dynamic DNS

If you have a simple home router with a dynamic IP but still want to access your content from the internet, you need to set-up a Dynamic DNS. There are paid services out there, but No-IP provides you with a free hostname (it does use ads, and hostnames expire every month). You will need to create an account with your VPN provider and then run the following:


docker run --name=noip -d \
  -v /etc/localtime:/etc/localtime:ro\
  -v [PATH_TO_CONFIG]:/config\
  coppit/no-ip


Note that [PATH_TO_CONFIG] must exist on your local hard-drive.

On your initial run, the container will create a file in the configuration directory. Open up that file, enter in your username, password and domain names. Then re-run your container and your dynamic DNS will be set-up!

NOTE: The rest of this guide will assume you have ports 443 and 80 forwarded on your modem to your Media PC. You may also need to poke a hole in any firewall you have for these ports. Without this completed then Traefik will not work.


Traefik for Reverse Proxy

Traefik will be used to take all traffic from your No-IP hostname and direct them to the desired services. Before you start:
  1. Create a folder to store your configuration data
  2. Create two empty files: traefik.toml and acme.json
  3. Make sure that acme.json has only 600 privileges (user read/write only, no execute, no permissions for group or other). I am unsure how to do this for Windows.
  4. Use htpassword or similar tool to encode a basic password auth string. In Linux, you would download it using sudo apt-get install apache2-utils and then run htpasswd -nb admin secure_password
  5. Put the following into traefik.toml (fill in your own variables for {!!EMAIL!!}, {!!DOMAIN!!}, and {!!HTPASSWORD_OUTPUT!!}):
################################################################
# Web configuration backend
################################################################
defaultEntryPoints = ["http","https"]
[entryPoints]
[entryPoints.http]
address = ":80"
#[entryPoints.http.redirect]
#entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]

[web]
address = ":8080"
[web.auth.basic]
users = ["admin:$apr1$62BTL9Hv$DvZO5S4l6FClkYbuxn4ag/"]

[accessLog]

################################################################
# Docker configuration backend
################################################################
[docker]
domain = "zeitoune.hopto.org"
watch = true
exposedbydefault = false

[acme]
email = "nassar.z@slair.com.au"
storage = "acme.json"
entryPoint = "https"
OnHostRule = true



Then run the following command to create your docker container:


docker run -d --name=traefik --restart always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v [PATH_TO_TRAEFIK]/traefik.toml:/traefik.toml \
  -v [PATH_TO_TRAEFIK]/acme.json:/acme.json \
  -l 'traefik.backend=traefik' \
  -l 'traefik.frontend.rule=PathPrefixStrip:/traefik' \
  -l 'traefik.enable=true' \
  -l 'traefik.docker.network=[DOCKER_NETWORK]' \
  -l 'traefik.port=8080' \
  --net=traefik \
  -p 80:80 -p 443:443 \
  --expose 8080 \
  traefik:latest


Note that [PATH_TO_TRAEFIK] must exist on your local hard-drive, and [DOCKER_NETWORK] is the network created using the command given at the start of this guide.

Once completed, you should be able to view traefik at https://[HOSTNAME]/traefik


Portainer for Docker Management

Portainer is a useful GUI tool for managing your docker containers (official installation instructions). Just run the following:

docker run -d --restart always \
  --name=portainer -p 9000:9000 --net=traefik \
  -v /etc/localtime:/etc/localtime:ro \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v [PATH_TO_DATA]:/data \
  -l 'traefik.backend=portainer' \
  -l 'traefik.frontend.rule=PathPrefixStrip:/portainer' \
  -l 'traefik.enable=true' \
  -l 'traefik.docker.network=[DOCKER_NETWORK]' \
  -l 'traefik.port=9000' \
portainer/portainer

Note that [PATH_TO_DATA] must exist on your local hard-drive. This is where all the Portainer configuration data will be stored, and is necessary in case you ever wish to update the container.

The portainer instance can now be viewed at https://[HOSTNAME]/portainer/ OR http://[IP_ADDRESS]:9000


Heimdall for Dashboard

Heimdall can be configured as a one-stop shop for accessing all of your configured microservices.


docker run -d --restart always \
  --name=heimdall \
  -v [PATH_TO_DATA]:/config \
  -e PGID=1000 \
  -e PUID=1000 \
  --net=traefik \
  -l 'traefik.backend=heimdall' \
  -l 'traefik.enable=true' \
  -l 'traefik.docker.network=traefik' \
  -l 'traefik.frontend.rule=Host:zeitoune.hopto.org' \
  -l 'traefik.frontend.priority=1'
  -l 'traefik.port=80' \
  linuxserver/heimdall

Note that [PATH_TO_DATA] must exist on your local hard-drive. This is where all the Heimdall configuration data will be stored, and is necessary in case you ever wish to update the container.

The heimdall instance can now be viewed at https://[HOSTNAME]/


Calibre for E-Books

Calibre is a management service for E-Books.

docker run -d --restart always \
  --name=calibre \
  -v [PATH_TO_BOOKS]:/books \
  -v [PATH_TO_APP]:/calibre-web/app \
  -v [PATH_TO_CONFIG]:/calibre-web/config \
  -v [PATH_TO_KINDLEGEN]:/calibre-web/kindlegen \
  -v /etc/localtime:/etc/localtime:ro \
  -e PGID=1000 \
  -e PUID=1000 \
  --net=traefik \
  -l 'traefik.backend=calibre' \
  -l 'traefik.enable=true' \
  -l 'traefik.docker.network=traefik' \
  -l 'traefik.frontend.rule=PathPrefixStrip:/calibre' \
  -l 'traefik.frontend.headers.customRequestHeaders=X-Script-Name:/calibre' \
  -l 'traefik.port=8083' \
  technosoft2000/calibre-web


Note that [PATH_TO_*] must exist on your local hard-drive. This is where all the Calibre data will be stored, and is necessary in case you ever wish to update the container.

The calibre instance can now be viewed at https://[HOSTNAME]/calibre


Ombi for requests

Use Ombi for making media requests.

docker run -d --restart always \
  --name=ombi \
  -v [PATH_TO_CONFIG]:/config \
  -e PGID=1000 \
  -e PUID=1000 \
  -e TZ=Australia/Sydney \
  --net=traefik \
  -l 'traefik.backend=ombi' \
  -l 'traefik.enable=true' \
  -l 'traefik.docker.network=traefik' \
  -l 'traefik.frontend.rule=PathPrefix:/ombi' \
  -l 'traefik.port=3579' \
  -p 3579:3579 \
  linuxserver/ombi

Note that [PATH_TO_CONFIG] must exist on your local hard-drive. This is where all the Ombi data will be stored, and is necessary in case you ever wish to update the container.

Note also that in this case I could only get Ombi to work by opening port 3576, navigating to the URL directly and editing the configuration so that the Base URL is '/ombi' instead of '/'. Once you have that configuration, you can close port 3579 again.

The ombi instance can now be viewed at https://[HOSTNAME]/ombi


Emby for Media

docker run -d --restart always \
  --name=emby \
  -v [PATH_TO_CONFIG]:/config \
  -v /etc/localtime:/etc/localtime:ro \
  -v [PATH_TO_MEDIA]:/media
  -e GID=1000 \
  -e UID=1000 \
  --net=traefik \
  -l 'traefik.backend=emby' \
  -l 'traefik.enable=true' \
  -l 'traefik.docker.network=traefik' \
  -l 'traefik.frontend.rule=PathPrefixStrip:/emby' \
  -l 'traefik.port=8096' \
  emby/embyserver

Note that [PATH_TO_*] must exist on your local hard-drive. This is where all the Emby data (and Media) will be stored, and is necessary in case you ever wish to update the container.

The Emby instance can now be viewed at https://[HOSTNAME]/emby/


Sonarr for TV shows

docker run -d --restart always \
  --name=sonarr \
  -v [PATH_TO_CONFIG]:/config \
  -v [PATH_TO_TV]:/tv \
  -v [PATH_TO_DOWNLOADS]:/downloads \
  -v /etc/localtime:/etc/localtime:ro \
  -e PGID=1000 \
  -e PUID=1000 \
  -e TZ=Australia/Sydney \
  --net=traefik \
  -l 'traefik.backend=sonarr' \
  -l 'traefik.enable=true' \
  -l 'traefik.docker.network=traefik' \
  -l 'traefik.frontend.headers.customRequestHeaders=X-Script-Name:/sonarr/' \
  -l 'traefik.frontend.rule=PathPrefix:/sonarr/' \
  -l 'traefik.port=8989' \
  --dns 8.8.8.8 --dns 8.8.4.4 \
linuxserver/sonarr

Note that [PATH_TO_*] must exist on your local hard-drive. This is where all the Sonarr data (and Media) will be stored, and is necessary in case you ever wish to update the container.

Note also that in this case I could only get Sonarr to work by opening port 8989, navigating to the URL directly and editing the configuration so that the Base URL is '/sonarr/' instead of '/'. Once you have that configuration, you can close port 3579 again.

The Sonarr instance can now be viewed at https://[HOSTNAME]/sonarr/


Radarr for Movies

docker run -d --restart always \
  --name=radarr \
  -v [PATH_TO_CONFIG]:/config \
  -v [PATH_TO_MOVIES]:/movies \
  -v [PATH_TO_DOWNLOADS]:/downloads \
  -v /etc/localtime:/etc/localtime:ro \
  -e PGID=1000 \
  -e PUID=1000 \
  -e TZ=Australia/Sydney \
  --net=traefik \
  -l 'traefik.backend=radarr' \
  -l 'traefik.enable=true' \
  -l 'traefik.docker.network=traefik' \
  -l 'traefik.frontend.headers.customRequestHeaders=X-Script-Name:/radarr/' \
  -l 'traefik.frontend.rule=PathPrefix:/radarr/' \
  -l 'traefik.port=7878' \
  --dns 8.8.8.8 --dns 8.8.4.4 \
  linuxserver/radarr

Note that [PATH_TO_*] must exist on your local hard-drive. This is where all the Radarr data (and Media) will be stored, and is necessary in case you ever wish to update the container.

Note also that in this case I could only get Radarr to work by opening port 7878, navigating to the URL directly and editing the configuration so that the Base URL is '/radarr/' instead of '/'. Once you have that configuration, you can close port 3579 again.

The Radarr instance can now be viewed at https://[HOSTNAME]/radarr/


Jackett for Indexers

docker run -d --restart always \
  --name=jackett \
  -v [PATH_TO_CONFIG]:/config \
  -v [PATH_TO_DOWNLOAD]:/downloads \
  -v /etc/localtime:/etc/localtime:ro \
  -p 9117:9117 \
  -e PUID=1000 -e PGID=1000 \
  -e TZ=Australia/Sydney \
  --net=traefik \
  -l 'traefik.enable=true' \
  -l 'traefik.backend=jackett' \
  -l 'traefik.frontend.rule=PathPrefix:/jackett' \
  -l 'traefik.port=9117' \
  -l 'traefik.docker.network=traefik' \
  --dns 8.8.8.8 --dns 8.8.4.4 \
  linuxserver/jackett

Note that [PATH_TO_*] must exist on your local hard-drive. This is where all the data (and Media) will be stored, and is necessary in case you ever wish to update the container.


Tranmission for Torrents

This is being run with an inbuilt VPN:

docker run -d --restart always \
  --name=transmission \
  --cap-add=NET_ADMIN --device=/dev/net/tun \
  -v /[PATH_TO_CONFIG]:/config \
  -v /[PATH_TO_DOWNLOADS]:/data \
  -v /etc/localtime:/etc/localtime:ro \
  -e OPENVPN_PROVIDER=PIA \
  -e OPENVPN_CONFIG=Netherlands \
  -e OPENVPN_USERNAME=user \
  -e OPENVPN_PASSWORD=pass \
  -e WEBPROXY_ENABLED=false \
  -e LOCAL_NETWORK=192.168.0.0/16 \
  -e TRANSMISSION_RPC_AUTHENTICATION_REQUIRED=true \
  -e TRANSMISSION_RPC_PASSWORD=[PASSWORD] \
  -e TRANSMISSION_RPC_USERNAME=admin \
  -e TRANSMISSION_RPC_HOST_WHITELIST="127.0.0.1,192.168.0.*" \
  --log-driver json-file \
  --log-opt max-size=10m \
  --net=traefik \
  --dns 8.8.8.8 --dns 8.8.4.4 \
  -p 9091:9091 \
  -l 'traefik.backend=transmission' \
  -l 'traefik.enable=true' \
  -l 'traefik.docker.network=traefik' \
  -l 'traefik.frontend.rule=PathPrefix:/transmission' \
  -l 'traefik.port=9091' \
haugene/transmission-openvpn

Note that [PATH_TO_*] must exist on your local hard-drive. This is where all the data (and Media) will be stored, and is necessary in case you ever wish to update the container.


Inspirations

This post was inspired by the following: