HTPC, Docker, and Private Internet Access

HTPC, Docker, and Private Internet Access

Summary

This guide will walk you through the process of setting up an HTPC docker stack that routes everything through a VPN. I'm using Private Internet Access, but the VPN docker container is designed to work with a bunch of different providers. Please note the link above includes a referral code. All of the media-centric docker containers come from the outstanding work of the LinuxServer.io team. This guide does not walk through configuring the individual components.

Setup

Preface

This assumes you already have docker up and running. I'm running this on Arch Linux in a Proxmox container, but it should be the same across most distros.

Docker Containers

For reference, these are the containers that are used:

System Settings

I've got a homebrew NAS/HTPC setup using Arch Linux and ZFS. There are a few variables you'll need to change based on your setup, but it should be fairly straight-forward. These are run under the uid:gid of 1000:1000 which is typically the first user that you've added to your system. More of that in a minute when we get to the LinuxServer.io containers and how that is leveraged. The setup looks like this:

# The directory that holds my docker-compose files
mkdir -p /opt/dockerfiles/htpc

# The directory that holds configurations
mkdir -p /opt/htpc

# The directory where all of my media is stored
mkdir -p /storage00/media/htpc

# Set the permissions on the above
sudo chown -R 1000:1000 /opt/dockerfiles/htpc
sudo chown -R 1000:1000 /opt/htpc
sudo chown -R 1000:1000 /storage00/media/htpc

Creating the Docker Environment

Next we'll create a .env file that allows us to reuse values throughout the docker-compose.yml file that we'll create. Creating the file is simple enough:

# Create the file
vi /opt/dockerfiles/htpc/.env

Now add the following to the file created above:

# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
TZ=America/Detroit
# The UID and GID that I'd mentioned above.
PUID=1000
PGID=1000
# The directory where data and configuration will be stored.
ROOT=/opt/htpc
MEDIA=/storage00/media/htpc

Next we'll create the docker-compose.yml file. You'll see where the variables above are automatically reused throughout the file. A couple of notes from the file:

  • The Glueton containers acts as a VPN gateway for all the other containers, i.e. they need to route their connections through the VPN. It also acts as the front door for you to access the containers. The ports are listed in the docker-compose comments.  
  • The containers have dependencies so they start in the right order, e.g. Sonarr depends on Jackett which depends on Glueton.

And now for the docker-compose.yml file to bring it all together. First create the file:

# Create the file
vi /opt/dockerfiles/htpc/docker-compose.yml

Copy and paste the following into the file above. Please note that you'll need to customize the settings for the Glueton container:

version: '3'

services:
  gluetun:
    image: qmcgaw/private-internet-access
    container_name: gluetun
    cap_add:
      - NET_ADMIN
    network_mode: bridge
    ports:
      - 8888:8888/tcp # Tinyproxy
      - 8388:8388/tcp # Shadowsocks
      - 8388:8388/udp # Shadowsocks
      - 8000:8000/tcp # Built-in HTTP control server
      - 8112:8112 # deluge
      - 8989:8989 # sonarr
      - 9117:9117 # jackett
      - 7878:7878 # radarr
      - 6789:6789 # nzbget
      - 5076:5076 # hydra2
    # command:
    environment:
      - VPNSP=private internet access
      - TZ=${TZ}
      - USER=XXXXXXX # Your username
      - PASSWORD=YYYYYY # Your password
      - REGION=ZZZZZZ # Your region, e.g. US East. No quotes.
      - EXTRA_SUBNETS=10.0.0.0/8,192.168.0.0/16,172.16.0.0/12
    restart: unless-stopped

  deluge:
    container_name: deluge
    image: linuxserver/deluge
    restart: unless-stopped
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - ${MEDIA}/unsorted:/downloads
      - ${ROOT}/config/deluge:/config
    network_mode: service:gluetun 
    depends_on:
      - jackett
      - gluetun

  sonarr:
    container_name: sonarr
    image: linuxserver/sonarr
    restart: unless-stopped
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - ${ROOT}/config/sonarr:/config 
      - ${MEDIA}/tv:/tv 
      - ${MEDIA}/unsorted:/downloads 
    network_mode: service:gluetun
    depends_on:
      - jackett
      - gluetun

  jackett:
    container_name: jackett
    image: linuxserver/jackett
    restart: unless-stopped
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - ${MEDIA}/unsorted:/downloads
      - ${ROOT}/config/jackett:/config
    network_mode: service:gluetun
    depends_on:
      - gluetun

  radarr:
    container_name: radarr
    image: linuxserver/radarr
    restart: unless-stopped
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - ${ROOT}/config/radarr:/config 
      - ${MEDIA}/movies:/movies 
      - ${MEDIA}/unsorted:/downloads
    network_mode: service:gluetun
    depends_on:
      - jackett
      - gluetun

  nzbget:
    container_name: nzbget
    image: linuxserver/nzbget
    restart: unless-stopped
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ} 
    volumes:
      - ${MEDIA}/unsorted:/downloads 
      - ${ROOT}/config/nzbget:/config 
    network_mode: service:gluetun
    depends_on:
      - jackett
      - gluetun

  hydra2:
    image: linuxserver/nzbhydra2
    container_name: hydra2
    restart: unless-stopped
    environment:
      - PUID=${PUID} 
      - PGID=${PGID} 
      - TZ=${TZ} 
    network_mode: service:gluetun
    volumes:
      - ${ROOT}/config/hydra2:/config
      - ${MEDIA}/unsorted:/downloads
    depends_on:
      - gluetun
      - jackett

Assuming all goes well, you'll see a bunch of directories created based on the ENV variables that we'd set. For example:

[nlabadie@nas config]$ pwd
/opt/htpc/config
[nlabadie@nas config]$ ls
deluge  hydra2  jackett  nzbget  radarr  sonarr

[nlabadie@nas htpc]$ pwd
/storage00/media/htpc
[nlabadie@nas htpc]$ ls
movies  music  tv  unsorted

Conclusion

This should hopefully give you a starting point for your HTPC setup. I'm a fan of using Jellyfin as the server, and streaming the media using Infuse on Apple TV. They even make a fancy plugin for syncing the two.

You can access the individual services for setup by hitting the ports that are commented at the beginning of the docker-compose.yml file, specifically this:

- 8112:8112 # deluge
- 8989:8989 # sonarr
- 9117:9117 # jackett
- 7878:7878 # radarr
- 6789:6789 # nzbget
- 5076:5076 # hydra2

For example, if your hostname is nas.domain.lan, then you'd go to the following URL to access Jackett: http://nas.domain.lan:9117. The same goes for all the other services listed above, e.g. http://nas.domain.lan:8112 for Deluge.

Show Comments