/mediabox

🐳 docker-compose based MEDIABOX πŸ“Ί

Primary LanguageCSSMIT LicenseMIT

πŸ“Ί Mediabox

TL;DR

A home media server using docker-compose that enables SSL wildcard certificates via Cloudflare and LetsEncrypt. The approach allows layering of complexity and features including Single sign on (SSO) via GCP.

What's in the stack?

NOTE: These are listed in the order I recommend they are layered and tested during setup.

Baseline

traefik-cloudflare.yml and optional traefik-oauth.yml

  • Traefik - Service ingress, routing, etc, handles SSL certificates via DNS-01 challenge and LetsEncrypt

Misc

misc.yml and optional misc-oauth.yml

  • Watchtower - A process for automating Docker container base image updates
  • Duplicati - Backup software to store encrypted backups
  • Portainer

Multimedia

multimedia.yml, optional multimedia-oauth.yml

  • Prowlarr - quick start - Indexer/manager manager/proxy that supports management of both Torrent Trackers and Usenet Indexers. It integrates seamlessly with Lidarr, Radarr, Readarr, and Sonarr offering complete management of your indexers with no per app Indexer setup required. HINT: use local network names in settings e.g. http://prowlarr:9696, http://radarr:7878, http://sonarr:8989, http://sabnzbd:8080.
  • SABnzbd - Usenet downloader. Use top level DATA env variable to avoid needing to specify "Remote Path" it the *arr applications. This makes it easier to hardlink. See #Layered setup stage 2
  • Sonarr - should pull indexer from prowlarr
  • Radarr - should pull indexer from prowlarr
  • Plex - NOTE: in initial config, connect to http://<my-local-ip>:32400/web first to complete the setup wizard. Plex differs from every other container and uses host networking, therefore enable Remote access, port forward 32400 to <my-local-ip> and then you may access remotely via https://app.plex.tv. Using host networking makes configuration easier, and ensures traffic runs unrestricted and local devices can easily discover the server. The not-so-big-deal-downside is that plex.example.com no longer is your go-to url.
  • Organizr - Organize a single page with tabs to manage all services

Optional additions

NOTE: updates likely needed here.

Prerequisites

Initial setup

  1. Fork this repo (so you can keep changes if you need to)
  2. Clone your forked repo
  3. cd mediabox
  4. cp .env.template .env
  5. Replace variables on .env with whatever makes sense to you (follow the comments above each property). Don't worry, start with the basics and get to the rest later

NOTE: set up duplicati.example.com later to make sure your repo and specifically your .env is backed up daily.

Layered setup

Setting up a home server can be complex. For all examples, we will assume you are using the domain example.com. You usually need to setup your domain on cloudflare, forward ports on your router and set up dynamic dns. Before attempting to configure additional applications, this repo is setup to allow you to layer in complexity by minimizing containers started using the COMPOSE_FILE variable. The simple shell script wraps the docker-compose command to make it simple to execute up, down, restart, logs, shell and most any other typical docker-compose command (via cmd). See Usage or simply execute ./mb to see it.

Layered setup stage 1

Successful completion of this stage means you can access both https://traefik.example.com and https://whoami.example.com, with optional IP whitelist restriction and/or optional Single Sign On.

  1. Set up cloudflare DNS for your example.com domain
  2. Set up dynamic DNS to cloudflare to update the A record for your example.com
  3. Add wildcard CNAME - Add a * CNAME to @
  4. Increase cloudflare security - Configure increased security on your cloudflare zone, see Cloudflare Settings for Traefik Docker: DDNS, CNAMEs, & Tweaks
  5. Verify HTTPS connectivity - In .env set COMPOSE_FILE=traefik-cloudflare.yml, DOMAIN,SSL_ACME_EMAIL,CF_API_EMAIL,CF_API_KEY and ./mb up - verify connectivity to both https://traefik.example.com and https://whoami.example.com. Check logs with ./mb logs traefik and make sure there are no errors. ./mb down when done.
  6. (optional) Restrict IPs allowed - Restrict your IP_WHITELIST_SOURCERANGE in .env to a minimal set of IP addresses, or if you want it public, leave it open by default 0.0.0.0/0
  7. (optional) Setup Single Sign On - Set COMPOSE_FILE=traefik-cloudflare.yml:traefik-oauth.yml in .env and ./mb up - set up GCP based SSO via OAUTH. Some background is available here on the external steps, but as-is you only need to make sure your associated ENV variables are populated. Now verify the auth challenge to both https://traefik.example.com and https://whoami.example.com. ./mb down when done.

All good? If not do not continue.

Layered setup stage 2

Plan your disk layout and set up your NFS (or other) disk mounts (beyond the scope of this readme). This setup follows best practices mentioned on this article and this reddit post to be able to use hardlinks and/or perform atomic move operations instead of copy+delete (which takes longer and requires more space).

TL;DR from Trash guides "how to set up for docker":

The paths you use on the inside matter. Because of how Docker’s volumes work, passing in two or three volumes such as the commonly suggested /tv, /movies and /downloads makes them look like two or three file systems, even if they aren’t. This means hard links won’t work and instead of an instant move, a slower and more I/O intensive copy + delete is used.

# My disks layout:
#
# β”œβ”€β”€ nas
# β”‚   └── mediabox (mounted as /data)
# |       β”œβ”€β”€ backups
# |       β”œβ”€β”€ torrents
# β”‚       |   β”œβ”€β”€ movies
# β”‚       |   β”œβ”€β”€ pictures
# β”‚       |   └── tv
# |       └── usenet
# β”‚       |   β”œβ”€β”€ movies
# β”‚       |   β”œβ”€β”€ pictures
# β”‚       |   └── tv
# |       └── media
# β”‚           β”œβ”€β”€ movies
# β”‚           β”œβ”€β”€ pictures
# β”‚           └── tv
# └── ssd
#     β”œβ”€β”€ containers
#     └── repo
#
# CONTAINERS : Application docker container storage - SSD recommended.  Intend to backup this to the BACKUPS.
# DATA       : This directory will be the top level mount point mounted in containers.  Configure relative paths inside the applications.
# BACKUPS    : Target location for backups (can also use online services instead inside duplicati)
#
CONTAINERS=/containers
DATA=/mnt/nfs/mediabox
BACKUPS=/mnt/nfs/mediabox/backups

Layered setup stage 3

Now it is time to determine what services you want to run.

  1. Add primary applications - Edit your .env and chain mediabox.yml on to your COMPOSE_FILE variable. The same as above, ./mb up then check the logs of the various containers like ./mb logs plex. You should now be able to access each by name e.g. https://plex.example.com.
  2. (optional) Protect applications with SSO - Edit your .env and chain mediabox-oauth.yml on to your COMPOSE_FILE variable. Test again, but this time use an incognito browser (or other browser that has not utilized SSO in steps above) and be sure you receive a challenge for https://plex.example.com
  3. (optional) Torrents, books, etc - view the remainder of the compose files and see what services you want. Using the same methodology, chain the compose file, and test your changes. (I am not using torrents or books, so these may need adjustments, feel free to PR changes)

Usage

usage: mb [help|-h|--help] <subcommand>

optional arguments:
  help | -h | --help
    print this message and exit

subcommands:
  start
     starts the configured files
  stop
     stops
  restart
     restarts, a combination of stop and start
  update
     pulls updated images
  shell
     open a shell to the targeted container
  logs
     shows logs
  docompose <command>
     executes any arbitrary docker compose command. Use "docompose help" to list them


The logs subcommand can be appended by flags and specify the container(s). example: 

  mb logs -f --tail 500 plex
    shows logs only for plex service


Be sure to run commands either with sudo, or as a user who is part of the "docker" group

Updating

Watchtower automatically updates all apps (if docker image update is available) at 4 AM every day.

VPN (may need updating)

With OpenVPN you can use any VPN provider following these steps:

  1. Download your VPN OpenVPN config files (e.g: NordVPN TCP/UDP config files)
  2. Download your VPN CA file (e.g: NordVPN CA & TLS key files)
  3. Run the following (using NordVPN Brazil#65 as example)
# Copy required files
cp ~/Downloads/br65.nordvpn.com.udp.ovpn ${OPENVPN}/vpn.conf
cp ~/Downloads/br65_nordvpn_com_ca.crt ${OPENVPN}/vpn-ca.crt

# Write credentials
cat <<EOT >> ${OPENVPN}/vpn.auth
you@mail.com
YourVPNP4ssw0rD
EOT

Credit

Much of this repo was developed by the original other and contributors at https://github.com/cristianmiranda/mediabox. I did not choose to PR my changes because the repo was not very active. While a PR from this repo could be created and applied upstream, I did not want to take the time to justify choices I made including some structural changes. If someone wants to do that work to push this upstream, I welcome getting my changes contributed to the original body of work.

Anyway, thanks to @christianmiranda and other contributors from the original repo.