Docker @ Home? Why yes!

For years I’ve run a personal home server.  Well scratch that, maybe I should call it a lab.  I’ve been a long-term user of VSphere at home, and over the years I’ve slowly but surely expanded our environment to be more akin to a small business setup.  It’s a hobby, and I enjoy it.  Why not?

Recently while visiting r/homelab, I ran across a post about a guy who set up a linux host running docker all of his home media applications.  Docker?  What the heck is docker?  Why do I need that when I can just spin-up VMs.  Or how about a better question… Why do I need that when I can just install all of these apps in a single VM?

In short – here are the advantages:

  • Less resource intensive than separate VMs.  (Duh!)
  • Complete environment isolation, meaning no more mono-libs or java libs cluttering up your host server.
  • Speaking of Libs – having the RIGHT environment for the app you are running.  What I need an OLD version of PHP to run this?  No big deal!
  • Separation of configuration data from application data.
  • EASY upgrades docker pull / docker run / docker rm.  Or my personal favorite… just script it!
  • Quick and easy deployment of new tools/toys to play with without causing harm to the rest of your system.

There are MANY other reasons to use docker, especially when it comes to development (both linux and web development).  I won’t get into that here.  Mostly logging this setup for myself. I’ll share after the break how I set up a brand new Ubuntu 16.04 VM with docker, and migrated my entire home media server to it in one night.

Before continuing – I always give credit where it’s due. Much of my inspiration came from this post [zackreed.me]. Check it out for more (likely better written) posts similar to this one!

Read More…

Setting up your System

Install your base OS.  In my case I used Ubuntu 16.04 LTS.  Why Ubuntu?  Well, I like it.  I’ve used it long enough to not have to google-fu how to do the majority of configuration you need to get up and running.

Upgrade packages and system

sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade

Install NFS-Common for NFS Share Mounting.  I use this to copy files back and forth to my NAS.

sudo apt-get install nfs-common

Update your NAS to accept secure connections from a specific IP.  You can also do a username/password login, but I prefer to keep my fstab clean.

Update /etc/fstab to include your mountpoints

10.0.22.24:/volume1/tv        /media/tv        nfs    rw,hard,intr    0    0
10.0.22.24:/volume1/movies    /media/movies    nfs    rw,hard,intr    0    0
10.0.22.24:/volume1/downloads /media/downloads nfs    rw,hard,intr    0    0

Install Docker

curl -fsSL https://get.docker.com/ | sh

New Docker Server Setup

mkdir -p /docker/containers/{couchpotato,muximux,nzbget,plex,plexpy,sonarr}
chown -R user:user /docker
mkdir -p /docker/downloads/{completed/Movies,completed/TV}
mkdir -p /docker/containers/couchpotato/config
mkdir -p /docker/containers/muximux/config
mkdir -p /docker/containers/nzbget/config
mkdir -p /docker/containers/plex/{config,transcode}
mkdir -p /docker/containers/plexpy/config
mkdir -p /docker/containers/sonarr/config

Install muximux

docker create \
 --name=muximux \
 -p 80:80 \
 -p 443:443 \
 -v /docker/containers/muximux/config:/config \
 linuxserver/muximux

Create systemd startup script

vi /lib/systemd/system/muximux.service

Add this content

[Unit]
 Description=muximux container
 Requires=docker.service
 After=docker.service

[Service]
 User=dencur
 Restart=on-failure
 RestartSec=45
 ExecStart=/usr/bin/docker start -a muximux
 ExecStop=/usr/bin/docker stop -t 2 muximux

[Install]
 WantedBy=multi-user.target

Enable on startup

systemctl enable muximux.service

If you want to start it up for testing

systemctl start muximux

Create the upgrade script

vi ~/bin/updatemuximux

Paste this into the script

#!/bin/bash
# Define a timestamp function
timestamp() {
 date +"%Y-%m-%d_%H-%M-%S"
}
timestamp
echo "Pulling Latest from linuxserver/muximux"
docker pull linuxserver/muximux 
echo "Stopping muximux Container"
docker stop muximux
echo "Backing up old muximux Container to muximux_$(timestamp)"
docker rename muximux muximux_$(timestamp)
echo "Creating and starting new muximux Server"
docker create \
--name=muximux \
-p 80:80 \
-p 443:443 \
-v /docker/containers/muximux/config:/config \
linuxserver/muximux
docker start muximux

Setup Plex

docker create \
 --name=plex \
 --net=host \
 -e VERSION=latest \
 -e PUID=1000 -e PGID=1000 \
 -v /docker/containers/plex/config:/config \
 -v /media/tv:/media/tv \
 -v /media/movies:/media/movies \
 linuxserver/plex

Rsync over the old plex server

rsync -vaE --exclude 'Cache' \
 --progress \
 /var/lib/plexmediaserver/Library/Application\ Support/Plex\ Media\ Server \
 user@remoteserver:~/plexstuff/

Create systemd startup script

vi /lib/systemd/system/plex.service

Add this content

[Unit]
 Description=Plex container
 Requires=docker.service
 After=docker.service

[Service]
 User=dencur
 Restart=on-failure
 RestartSec=45
 ExecStart=/usr/bin/docker start -a plex
 ExecStop=/usr/bin/docker stop -t 2 plex

[Install]
 WantedBy=multi-user.target

Enable on startup

systemctl enable plex.service

If you want to start it up for testing

systemctl start plex

Create the upgrade script

vi ~/bin/updateplex

Paste this into the script

#!/bin/bash
# Define a timestamp function
timestamp() {
 date +"%Y-%m-%d_%H-%M-%S"
}
timestamp
echo "Pulling Latest from linuxserver/plex"
docker pull linuxserver/plex
echo "Stopping plex Container"
docker stop plex
echo "Backing up old plex Container to plex_$(timestamp)"
docker rename plex plex_$(timestamp)
echo "Creating and starting new plex Server"
docker create \
--name=plex \
--net=host \
-e VERSION=latest \
-e PUID=1000 -e PGID=1000 \
-v /docker/containers/plex/config:/config \
-v /media/tv:/media/tv \
-v /media/movies:/media/movies \
linuxserver/plex
docker start plex

Setup NZBGet

docker create \
 --name nzbget \
 -p 6789:6789 \
 -e PUID=1000 -e PGID=1000 \
 -v /docker/containers/nzbget/config:/config \
 -v /media/downloads/complete:/downloads/complete \
 -v /media/downloads/incomplete:/downloads/incomplete \
 linuxserver/nzbget

Logged into the web portal and did a bunch of configuration stuff to point to the right folders.

Create systemd startup script

vi /lib/systemd/system/nzbget.service

Add this content

[Unit]
 Description=NZBGet container
 Requires=docker.service
 After=docker.service

[Service]
 User=dencur
 Restart=on-failure
 RestartSec=45
 ExecStart=/usr/bin/docker start -a nzbget
 ExecStop=/usr/bin/docker stop -t 2 nzbget

[Install]
 WantedBy=multi-user.target

Enable on startup

systemctl enable nzbget.service

If you want to start it up for testing

systemctl start nzbget

Create the upgrade script

vi ~/bin/updatenzbget

Paste this into the script

#!/bin/bash
# Define a timestamp function
timestamp() {
 date +"%Y-%m-%d_%H-%M-%S"
}
timestamp
echo "Pulling Latest from linuxserver/nzbget"
docker pull linuxserver/nzbget
echo "Stopping nzbget Container"
docker stop nzbget
echo "Backing up old nzbget Container to nzbget_$(timestamp)"
docker rename nzbget nzbget_$(timestamp)
echo "Creating and starting new nzbget Server"
docker create \
--name nzbget \
-p 6789:6789 \
-e PUID=1000 -e PGID=1000 \
-v /docker/containers/nzbget/config:/config \
-v /media/downloads/complete:/downloads/complete \
-v /media/downloads/incomplete:/downloads/incomplete \
linuxserver/nzbget
docker start nzbget

Setup Couch Potato

docker create \
 --name=couchpotato \
 -v /etc/localtime:/etc/localtime:ro \
 -v /docker/containers/couchpotato/config:/config \
 -v /media/downloads/complete/Movies:/downloads \
 -v /media/movies:/movies \
 -e PGID=1000 -e PUID=1000 \
 -p 5050:5050 \
 linuxserver/couchpotato

Create systemd startup script

vi /lib/systemd/system/couchpotato.service

Add this content

[Unit]
 Description=Couchpotato container
 Requires=docker.service
 After=docker.service

[Service]
 User=dencur
 Restart=on-failure
 RestartSec=45
 ExecStart=/usr/bin/docker start -a couchpotato
 ExecStop=/usr/bin/docker stop -t 2 couchpotato

[Install]
 WantedBy=multi-user.target

Enable on startup

systemctl enable couchpotato.service

If you want to start it up for testing

systemctl start couchpotato

Create the upgrade script

vi ~/bin/updatecouchpotato

Paste this into the script

#!/bin/bash
# Define a timestamp function
timestamp() {
 date +"%Y-%m-%d_%H-%M-%S"
}
timestamp
echo "Pulling Latest from linuxserver/couchpotato"
docker pull linuxserver/couchpotato
echo "Stopping CouchPotato Container"
docker stop couchpotato
echo "Backing up old CouchPotato Container to couchpotato_$(timestamp)"
docker rename couchpotato couchpotato_$(timestamp)
echo "Creating and starting new CouchPotato Server"
docker create \
--name=couchpotato \
-v /etc/localtime:/etc/localtime:ro \
-v /docker/containers/couchpotato/config:/config \
-v /media/downloads/complete/Movies:/downloads \
-v /media/movies:/movies \
-e PGID=1000 -e PUID=1000 \
-p 5050:5050 \
linuxserver/couchpotato
docker start couchpotato

Update Couchpotato notify from Preferences.xml Auth Token

Setup Sonarr

If you are moving Sonarr go to your current instance look up the General->Info, the bottom item is where the database is stored. Copy this folder into your /config folder before starting the VM

Sonarr docker

docker create \
 --name sonarr \
 -p 8989:8989 \
 -e PUID=1000 -e PGID=1000 \
 -v /dev/rtc:/dev/rtc:ro \
 -v /docker/containers/sonarr/config:/config \
 -v /media/tv:/media/tv \
 -v /media/downloads/complete/tv:/downloads/complete/tv \
 -v /media/downloads/complete/tv_manual:/downloads/complete/tv_manual \
 linuxserver/sonarr

Create systemd startup script

vi /lib/systemd/system/sonarr.service

Add this content

[Unit]
 Description=Sonarr container
 Requires=docker.service
 After=docker.service

[Service]
 User=dencur
 Restart=on-failure
 RestartSec=45
 ExecStart=/usr/bin/docker start -a sonarr
 ExecStop=/usr/bin/docker stop -t 2 sonarr

[Install]
 WantedBy=multi-user.target

Enable on startup

systemctl enable sonarr.service

If you want to start it up for testing

systemctl start sonarr

Create the upgrade script

vi ~/bin/updatesonarr

Paste this into the script

#!/bin/bash
# Define a timestamp function
timestamp() {
 date +"%Y-%m-%d_%H-%M-%S"
}
timestamp
echo "Pulling Latest from linuxserver/sonarr"
docker pull linuxserver/sonarr
echo "Stopping sonarr Container"
docker stop sonarr
echo "Backing up old sonarr Container to sonarr_$(timestamp)"
docker rename sonarr sonarr_$(timestamp)
echo "Creating and starting new sonarr Server"
docker create \
--name sonarr \
-p 8989:8989 \
-e PUID=1000 -e PGID=1000 \
-v /dev/rtc:/dev/rtc:ro \
-v /docker/containers/sonarr/config:/config \
-v /media/tv:/media/tv \
-v /media/downloads/complete/tv:/downloads/complete/tv \
-v /media/downloads/complete/tv_manual:/downloads/complete/tv_manual \
linuxserver/sonarr
docker start sonarr

Install Plexpy

docker create \
  --name=plexpy \
  -v /etc/localtime:/etc/localtime:ro \
  -v /docker/containers/plexpy/config:/config \
  -v /docker/containers/plex/config/Library/Application\ Support/Plex\ Media\ Server/Logs:/logs:ro \
  -e PGID=1000 -e PUID=1000 \
  -p 8181:8181 \
  linuxserver/plexpy

Create systemd startup script

vi /lib/systemd/system/plexpy.service

Add this content

[Unit]
 Description=Plexpy container
 Requires=docker.service
 After=docker.service

[Service]
 User=dencur
 Restart=on-failure
 RestartSec=45
 ExecStart=/usr/bin/docker start -a plexpy
 ExecStop=/usr/bin/docker stop -t 2 plexpy

[Install]
 WantedBy=multi-user.target

Enable on startup

systemctl enable plexpy.service

If you want to start it up for testing

systemctl start plexpy

Create the upgrade script

vi ~/bin/updateplexpy

Paste this into the script

#!/bin/bash
# Define a timestamp function
timestamp() {
 date +"%Y-%m-%d_%H-%M-%S"
}
timestamp
echo "Pulling Latest from linuxserver/plexpy"
docker pull linuxserver/plexpy
echo "Stopping plexpy Container"
docker stop plexpy
echo "Backing up old plex Container to plex_$(timestamp)"
docker rename plexpy plexpy_$(timestamp)
echo "Creating and starting new plexpy Server"
docker create \
--name=plexpy \
-v /etc/localtime:/etc/localtime:ro \
-v /docker/containers/plexpy/config:/config \
-v /docker/containers/plex/config/Library/Application\ Support/Plex\ Media\ Server/Logs:/logs:ro \
-e PGID=1000 -e PUID=1000 \
-p 8181:8181 \
linuxserver/plexpy
docker start plexpy

Enable Docker Sockets

I like to enable Docker sockets on my docker servers so I can use some 3rd party tools to monitor status. Admittedly I don’t use these often, but if you’re interested in accessing docker information from a tool like the Chrome App – Docker UI. Turn on the port access by doing the steps below.

Create a file called to make docker available on a TCP socket on port 2375:

vi /etc/systemd/system/docker-tcp.socket
[Unit]
 Description=Docker Socket for the API

[Socket]
 ListenStream=2375
 BindIPv6Only=both
 Service=docker.service

[Install]
 WantedBy=sockets.target

Then enable this new socket:

systemctl enable docker-tcp.socket
systemctl enable docker.socket
systemctl stop docker
systemctl start docker-tcp.socket
systemctl start docker

Let me know how it goes!

Loading Disqus Comments ...
Loading Facebook Comments ...