Many people have emailed me after reading Docker and Traefik guides, asking how I prep my Docker Server OS before starting to build my stack. Or, what to do after setting up a Docker stack.
That got me thinking. It's time to revise my Docker and Traefik guides anyways. So why not do a full series of posts from beginning to end on how I build my Docker Stack for Home Server, Media Server, Web Server, DNS/Adblock Server, and Synology NAS.
So, I decided to put together this series:
Ultimate Docker Server Series:
This post is part of the Docker Server Tutorial Series, which includes the following individual chapters/parts:- Ultimate Docker Server: Getting Started with OS Preparation [VIDEO] [2024]
- Docker Media Server Ubuntu/Debian with 60+ Awesome Apps [VIDEO] [2024]
- ZeroTier VPN Ubuntu, Docker, Synology, Windows: Secure on-the-go access [coming soon]
- Nginx Proxy Manager Docker Compose Guide: Simplest Reverse Proxy [coming soon]
- Traefik Reverse Proxy
- Authelia Docker Compose Guide: Secure 2-Factor Authentication [VIDEO] [2024]
- Google OAuth Docker Compose Guide: Multi-Factor Authentication [VIDEO] [2024]
- Docker Security Practices for Homelab: Secrets, Firewall, and more
- Cloudflare Settings for Docker Traefik Stacks
- Implementing a Backup System for Docker Traefik Stack [coming soon]
- Automate Homelab Setup Deployarr: 60+ Apps in Minutes
This post covers all the basic and good-to-know information before starting the Docker Server setup.
Table of Contents
Automating the Docker Reverse Proxy Stack Setup
If you have not heard of Auto-Traefik, then you should consider checking out this post or watching the video series below:
Auto-Traefik was launched as a perk to my supporters and to find a way to financially support what I do with this site.
With the launch of this video series, I am revising all my guides to align with what I have implemented with Auto-Traefik.
Everything that the Auto-Traefik Script does should be possible by following this series without paying for Auto-Traefik. But my hope is that you continue to support my work by becoming a member.
Be the 1 in 200,000. Help us sustain what we do.You will gain benefits such as discord roles, exclusive content, ad-free browsing, raffles, and more.Become a Sponsor (starting from just $1.67/month)
My Environment
Wait why do I need to read about some random guy's environment?
You do not have to. But I publish all my "real" setup on my Github Repo. Since I sync all Docker related configuration files between all m Docker hosts (more on this below), it is important to differentiate them with prefixes, suffixes, folders, etc.
Therefore, to follow my guides and GitHub repo, it can be beneficial to understand my environment.
My Docker Server Hosts
I have 5 docker hosts. I sync all my Docker stacks using Syncthing and push the files to GitHub so I can share with the community.
Syncing also allows me to have a backup of one system's configuration file in all the other hosts.
For this reason, where applicable, I segregate or name files/folders with their hostname (for example: hs for Home Server):
- docker-compose-hs.yml: Docker Compose for Home Server on Ubuntu Server Proxmox LXC Container.
- docker-compose-mds.yml: Docker Compose for Media/Database Server on Ubuntu Server Proxmox LXC Container.
- docker-compose-dns.yml: Docker Compose for AdBlock/ DNS Server on Raspberry Pi 4B
- docker-compose-ws.yml: Docker Compose for Web Server on Digital Ocean VPS, which powers this website.
- docker-compose-ds918.yml: Docker Compose for Synology DS918+ NAS.
You may not have to Sync or push the files out to GitHub. Therefore, you may omit the hostname (adjust wherever applicable). But eventually if you plan to go towards a multi-host setup without getting into Docker Swarm etc., then my way could help.
My GitHub Repository
In my GitHub Repo, you see the current working version of my Docker server stacks.
This Docker series is fully based on my GitHub repository.
Using the Docker Compose from My Github Repo
Even though all Docker files from my hosts are all combined and pushed to the repo, the compose files are all located in the folder called, well, compose.
The archives folder has all my old/unused Docker Compose files, the hs folder has all my home server Docker Compose YMLs, the mds folder has all my media/database server Docker Compose YMLs, and so on.
The docker compose examples can be copy-pasted as-is from one file to another, in most cases. In fact, you might even find the same the same service on multiple hosts (e.g. Traefik, Socket Proxy, Portainer, etc.).
Typical Target Users
If you are reading this, there is a high chance that you are trying to setup your Home Media Server.
A Home Media Server is a server located in your home network that acts as a central data storage and serving device. It is a key part of most "homelabs".
Typically, a home server is always on, has tons of storage capacity and ready to serve files (including media) when the need arises. We have covered several home server topics in great detail in the past. If you do not yet have a home server or are considering building one, then read this summary on the most common NAS or Home Server uses.
In my case, my Proxmox Server runs my Home Server, Media/Database Server, and AdBlock/DNS Server as Ubuntu 22.04 LXC Containers. I recently upgraded to the TopTon V700 Mini PC as Proxmox Host (for just $481, tax included) and it's been killing it:
- TopTon V700 Mini PC with Intel 13th Gen "Raptor Lake" i7-13800H - $481
- 2x32GB Crucial DDR5 4800MHz SO-DIMM RAM - $163
- 2x2TB Crucial T500 PCIe Gen4 M.2 NVME Drives in ZFS RAID - $230
- 4TB Crucial MX500 SATA III SSD for non-critical data, cache, etc. - $200
The principles discussed in this Docker Server series also apply to the setup of any Docker Stack, including web servers. For simplicity, I will generically refer to them as "Docker Server". [Read: 5 Best Mini PC for Proxmox Home Server [2024]]
Choosing Right OS for Docker Server
Let's start with choosing the best operating system for your Docker stack. We have a separate article that discusses all the best home server OS options available for you.
In my opinion, Ubuntu Server (or Debian Server) is the best one to choose if you like building things from scratch and learning along the way. Maybe I am biased due to my 14 years of experience with Ubuntu, but it won't be a wrong choice.
An even more ideal setup is to run a Type 1 hypervisor and virtualize your Docker server in a container or virtual machine. [Read: Proxmox vs ESXi: 9 Compelling reasons why my choice was clear]
With VMware free version and perpetual licenses going away, this is the best time to make the switch Proxmox VE.
Having said that, the docker compose examples in this guide will also work on Network Attached Storage devices such as Synology or QNAP:
- Ultimate Synology NAS Docker Compose Media Server
- Ultimate QNAP Docker Compose and Container Station Guide
Preparing Ubuntu/Debian for Docker Server
At this point, I will assume that you have a freshly installed Ubuntu/Debian operating system with nothing done after.
1. Create a New User
Some operating systems allow the creation of a non-root user during installation and some do not. If you did not create a primary user during setup, use the following commands to create it:
sudo adduser anand sudo adduser anand sudo
With the first command, we are adding a new user called "anand". The second command I am adding "anand" to the "sudo" group, so I have the privilege to use sudo command.
2. Update the OS
Most fresh OS installations lack all the security and package updates. So, let's take care of that next.
Run the following commands to refresh the packages list and install any updates.
sudo apt update sudo apt upgrade
3. Secure SSH Access
Until this point, you are probably physically in front of the server or a web-based console offered by the host/provider (e.g. Proxmox or VPS provider such as Digital Ocean).
Let's enable SSH access. Edit /etc/ssh/sshd_config using the following command:
nano /etc/ssh/sshd_config
Find the port line, uncomment it by removing the # in front (if it has one) and change the port number from default 22 to something random (e.g. 2053).
port 2053
Restart SSH server using the following command:
sudo systemctl restart sshd
In addition, an intrusion prevention system such as CrowdSec + Host Firewall Bouncer is also recommended (you may do this using our CrowdSec Docker guides, after completing this series).
How-To Series: Crowd Security Intrusion Prevention System
4. Install Basic/Required Packages
At this point, you may SSH into your server and continue remotely if you prefer. Let's install some basic/required packages (based on my experience).
sudo apt install ca-certificates curl gnupg lsb-release ntp htop zip unzip gnupg apt-transport-https ca-certificates net-tools ncdu apache2-utils
zip and unzip are for compression, net-tools is to check port usage and availability, htop provides a nice UI to see running processes, and ncdu helps visualize disk space usage.
5. Perform Server Tweaks
A few final system configuration tweaks to enhance the performance and handling of large list of files (e.g. Plex/Jellyfin metadata). Edit /etc/sysctl.conf using the following command:
sudo nano /etc/sysctl.conf
Add the following 3 lines at the end of the file:
vm.swappiness=10 vm.vfs_cache_pressure = 50 fs.inotify.max_user_watches=262144
Save and exit by pressing Ctrl X, Y, and Enter. That is all the prep work I do before I start building my Docker server stack.
6. Enable Firewall
Ubuntu/Debian systems come with a built-in firewall called UFW (Universal Firewall). It is disabled by default.
Let's start by adding some default policies (deny all incoming and allow all outgoing) and then allow incoming connections only from your local network (e.g. 192.168.1.0/24). Customize the network subnet based on your situation.
sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow from 192.168.1.0/24
This will allow all connections from devices in the IP range 192.168.1.1 to 192.168.1.254.
Then let's activate UFW using the command:
sudo ufw enable
Finally check the status of UFW using sudo ufw status, you should see that it is active with the rule we added above:
Concluding Remarks
If you have decided to follow this series and do things the way I do it, great. Keep in mind that my way is not the only way or even the best way.
But in the last 5 years or so of hosting my Docker Traefik repository (2.4k stars until Jan 2024) and the guides, I have yet to receive feedback saying my way sucks. So, I feel quite confident that it will meet most typical user's needs.
In addition, this website itself runs on the Docker web server stack in a production server on Digital Ocean. It has been performing well in handling the load and keeping everything secure.
If you do other things on your OS before getting started, be sure to share with the rest of us in the comments below.
That said, there may be other better ways to accomplish the same thing. Feel free to share them in the comments. With this series, I hope to teach my readers how they can replicate my Docker server stacks. So, let's begin the ride.