Ultimate Media Home Server using Ubuntu & Docker

My home server consists of using Freenas (setup for mass storage) and a dedicated compute server with ESXi (no local storage) to run numerous virtual machines.

I currently have a few different virutal machines running a 3CX phone server, Unifi Video, Ubuntu, Windows 10 and more.

I’m writing this article for a few friends that have asked me how I have my Docker container setup. To start, I’m using Ubuntu Server 16.04 & Docker to run my perfect home server.

Here are some of the Docker containers I use. This setup seems to be the most stable setup after spending months testing, fixing, rebuilding, tweaking, crashing, rebuilding again, and finally running smooth.

The Ubuntu and Docker Home Server Setup

First, log in as the sudo user.

sudo -i

Now install Docker.

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt-get update
apt-cache policy docker-ce
apt-get install -y docker-ce

I use environment variables to make it easier to change file paths. I tend to move folders around more often than I should.

To add more Ubuntu environment variables, edit the file:

sudo nano /etc/environment

Paste and save.

PUID=0
PGID=0
TZ="America/Los_Angeles"
USERNAME="username"
PASSWORD="password"
MEDIA="/mnt/nfs/media"
DOWNLOADS="/mnt/nfs/media/Downloads"
MOVIES="/mnt/nfs/media/Movies"
TVSHOWS="/mnt/nfs/media/TV\ Shows"
OPENVPN_USERNAME="USERNAME HERE"
OPENVPN_PASSWORD="PASSWORD HERE"

Docker Containers

Portainer
Used to have a nice GUI to edit docker containers.

docker run --name=portainer -d \
--restart=always \
-p 8999:9000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer:/data \
portainer/portainer

MySQL
I use this on containers that can be upgraded from SQLite to MySQL. Gives much better performance, even more so with NextCloud and my 50k of photos.

docker run --name=mysql -d \
-p 3306:3306 \
-v mysql:/var/lib/mysql \
-e PASSWORD=$PASSWORD \
mysql

NextCloud
I use this to keep a local backup of all my family photos and to back up my computer documents.

docker run --name=nextcloud -d \
--restart=always \
--link mysql:mysql \
-p 81:80 \
-p 3443:443 \
-v nextcloud:/var/www/html/config \
-v $MEDIA/CloudData:/var/www/html/data \
nextcloud

Home Assistant
This is the heart of my Smart Home. I use it to control all my devices (Phillips Hue) and all my Z-Wave devices.

docker run --name=hass -d \
--restart=always \
--privileged \
--cpus 2 \
--device=/dev/ttyACM0 \
-v $MEDIA/hass:/config \
-e PGID=0 -e PUID=0 \
-v /etc/localtime:/etc/localtime:ro \
-e TZ=$TZ \
-p 8123:8123 \
-p 1883:1883 \
-p 8080:8080 \
homeassistant/home-assistant

OpenVPN
Provides an easy to use and easy to setup VPN to my home network. I use it to have a more secure way of getting access to my FreeNAS and ESXi when not home.

docker run --name openvpn -d \
--net=host --privileged \
-v openvpn:/config \
-e INTERFACE=ens192 \
-e PGID=1001 -e PUID=1001 \
-e TZ=$TZ \
linuxserver/openvpn-as

Cloudflare DNS
My internet service provider wants $15/m for a static IP. Not worth it. So I use Cloudflare so I can point a domain to my home IP (used to access Security Cameras).

docker run --name ddns -d \
--restart unless-stopped \
-e EMAIL=EMAIL_HERE \
-e API_KEY=APIKEY_HERE \
-e ZONE=yourdomain.com \
oznu/cloudflare-ddns

Webserver using LetsEncrypt
I have tried other server dockers, even better more automated ones, but they lacked in the ability to edit the config file to customize the reverse proxy settings.

docker run --name=webserver -d \
--cap-add=NET_ADMIN \
-v letsencrypt_config:/config \
-e EMAIL=name@domain.tld \
-e URL=yourdomain.com \
-e SUBDOMAINS=sub,sub1.sub2,etc \
-e VALIDATION=http \
-p 80:80 -p 443:443 \
-e TZ=$TZ \
linuxserver/letsencrypt

To modify the nginx config file:

docker exec -it webserver nano /config/nginx/site-confs/default

Here is an example of how I have my nginx config.

# main server block
server {
	listen 443 ssl default_server;

	root /config/www;
	index index.html index.htm index.php;

	server_name _;

	# enable subfolder method reverse proxy confs
	include /config/nginx/proxy-confs/*.subfolder.conf;

	# all ssl related config moved to ssl.conf
	include /config/nginx/ssl.conf;

	client_max_body_size 0;

	location / {
		try_files $uri $uri/ /index.html /index.php?$args =404;
	}

	location ~ \.php$ {
		fastcgi_split_path_info ^(.+\.php)(/.+)$;
		# With php7-cgi alone:
		fastcgi_pass 127.0.0.1:9000;
		# With php7-fpm:
		#fastcgi_pass unix:/var/run/php7-fpm.sock;
		fastcgi_index index.php;
		include /etc/nginx/fastcgi_params;
	}

#redirect all to ssl
server {
    listen      80;
    server_name *.mydomain.com;

     #Rewrite all nonssl requests to ssl.
     return 301 https://$host$request_uri;
}

#NextCloud
server {
	listen 443 ssl;

	root /config/www;
	index index.html index.htm index.php;

	server_name cloud.*;

	include /config/nginx/ssl.conf;

	client_max_body_size 0;

	location / {
		#auth_basic "Restricted";
		#auth_basic_user_file /config/nginx/.htpasswd;
		include /config/nginx/proxy.conf;
		proxy_pass http://192.168.1.15:81;
	}
}

#ESXi
server {
	listen 443 ssl;

	root /config/www;
	index index.html index.htm index.php;

	server_name esxi.*;

	include /config/nginx/ssl.conf;

	client_max_body_size 0;

	location / {
		auth_basic "Restricted";
		auth_basic_user_file /config/nginx/.htpasswd;
		include /config/nginx/proxy.conf;
		proxy_ssl_verify off;
		proxy_pass https://192.168.1.11;
	}
}

#Freenas
server {
	listen 443 ssl;

	root /config/www;
	index index.html index.htm index.php;

	server_name freenas.*;

	include /config/nginx/ssl.conf;

	client_max_body_size 0;

	location / {
		auth_basic "Restricted";
		auth_basic_user_file /config/nginx/.htpasswd;
		include /config/nginx/proxy.conf;
		proxy_pass http://192.168.1.10;
	}
}

#Portainer
server {
	listen 443 ssl;

	root /config/www;
	index index.html index.htm index.php;

	server_name portainer.*;

	include /config/nginx/ssl.conf;

	client_max_body_size 0;

	location / {
		auth_basic "Restricted";
		auth_basic_user_file /config/nginx/.htpasswd;
		include /config/nginx/proxy.conf;
		proxy_pass http://192.168.40.15:8999;
	}
}

#Hass (Home Assistant)
server {
	listen 443 ssl;

	root /config/www;
	index index.html index.htm index.php;

	server_name hass.*;

	include /config/nginx/ssl.conf;

	client_max_body_size 0;

	proxy_buffering off;

	listen [::]:443 default_server ipv6only=off;

	add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";

	location / {
		include /config/nginx/proxy.conf;
		proxy_pass http://192.168.40.15:8123;

		proxy_set_header Host $host;
        proxy_redirect http:// https://;
        proxy_http_version 1.1;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
	}

	location /api/websocket {
        proxy_pass http://192.168.40.15:8123/api/websocket;
        proxy_set_header Host $host;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}
Follow
( 7 Followers )
X

Follow

E-mail : *

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.