homelab-docker
homelab-docker copied to clipboard
Docker Compose for building a home lab
A personal project to provide security, privacy, and data-ownership for my home.
Includes:
- Docker and various infrastructure concepts (data backups, parity)
- Self-Hosting for Privacy, such as: Adblocking, Passwords, Family Photos, Finances, Documents
- Self-Hosting for Entertainment, such as: Movies, TV Shows, Music, Board and Video Games
- Self-Hosting for Home, such as: Automation, Grocery Shopping
- Self-Hosting for Friends, such as: Event Scheduling, Idea Curation, Expense Management
- Practical Security: limit exposure surfaces, promote self-healing and proactive measures
- Practical Data Backup: easily export the most important files. Ideally, directly to the cloud and detached storage. Deterministic data is not prioritized.

Technology
The following apps / technologies are grouped into ./services/.
| Service | Note | Includes |
|---|---|---|
| adblock-and-dns | ||
| change-detect | ||
| dashboard | ||
| downloads | ||
| events | ||
| gloomhaven | ||
| infra | Required | docker socket proxy |
| image-board | ||
| media-request | ||
| media-streaming | ||
| monitor | ||
| paperless | ||
| public | Reverse Proxy and DDNS | |
| recipes | ||
| security | Run this if you're running public |
Explanation
Groupings are chosen based on context and dependencies. Most Services "stacks" should work fine without any other services (some exceptions exist) - allowing you to take from this repo what you care about and ignore the rest.
- All services use the same
.envfile in the root director. This is to simplify maintenance as some variables are used by multiple Services. This is accomplished via symlink. - Services should have one-way dependency. Stack A can be dependent on Containers within another Stack B, but Stack B cannot also be dependent any Containers in Stack A
- Can have any time of (efficient) dependencies within itself. Container A can depend on Container B
- Services are easy to manage (start, stop, restart,...) independently from one another.
Starting services
- Ensure you've established the symlink to
.env. See or execute./scripts/run-each-update.sh - Navigate to the desired service, eg
cd ./services/infra - Execute a standard docker compose up, eg
docker compose up -d
Notes
Watchtower is intentionally avoided based off advice from the Selfhosted.show podcast. The idea is to have full control over the versions of containers (rather than automated updates) to improve reliability. Instead, I use Diun and dockcheck.sh currently.
Install / Beginning
WIP
- Become familiar with the Project Structure below. This is your "map" of where to expect different things to be. In turn, this will help you configure your setup correctly
- SAMBA: After copying smb.conf, customize it as needed: interfaces, share names, users, passwords, etc.
Project Structure
Recommendations via multiple docker files, Where to Put Docker Compose, TRaSH Guides
File System
├── /opt
│ └── docker
│ └── homelab-docker (this repo)
│ ├── configtemplates (for help with non-docker tools eg. Samba or SnapRaid)
│ ├── scripts (for help with managing install, backups, etc)
│ ├── services
│ | ├── service1
| | | ├── docker-compose.yml
| | | ├── ~.env (symlink)
| | | ├── dockerfiles (for custom builds)
│ | | | └── *.dockerfile (for adhoc builds)
│ | | ├── configtemplates (service-specific configuration to be copied to config dir, then customized)
│ | | └── staticconfig (service-specific configuratio. does not move)
| | | ├── container1
| | | | └── container-specific-file.ext
| | | └── container*
│ | └── service*
│ └── .env (the master .env file. Each Service symlinks to this)
├── /srv
│ ├── docker (for container's configurations)
│ ├── cache
│ └── logs
└── /mnt/storage
├── db
├── staticfiles
│ ├── icons
│ ├── paperless
│ ├── tandoor_media
│ └── wallpaper
├── downloads
│ ├── audiobooks
│ ├── movies
│ ├── music
│ ├── paperless (shared r/w)
│ ├── podcasts
│ └── tv
└── media
├── audiobooks
├── music
├── pictures
├── podcasts
├── movies
└── tv
Directories may be created with the following cmds
Please review this script before running it. It is a work in progress and may not run as expected.
cd scripts
chmod +x start.sh
./start.sh
Recursively own the /data directory
sudo chown -R $USER:$USER /data
sudo chmod -R a=,a+rX,u+w,g+w /data
Docker Compose (and needed files)
/opt
explanation: reserved for the installation of add-on application software packages
This github repo represents this folder. It's safely committed to public repos and shouldn't contain anything sensitive.
Example files:
- ./docker-compose.yml
- ./.env
- ./dockerfiles/custom-build-for-caddy.dockerfile
- ./staticonfig/caddy/Caddyfile
Persistent Data and Configuration
/srv
How you configure the apps and their current states. This is separated from the Docker Compose (ie. "setup") as these become specific to how you use the services - not how they're installed/maintained.
Media Staging (such as magnets)
/mnt/storage/downloads
Media Storage (such as Podcasts, Movies, TV Shows, Audiobooks):
/mnt/storage/media/movies
/mnt/storage/media/podcasts
This creates a clear distinction between the files many services could use or want and the files those services just need to access. Separation presumably allows for alternate backup or hosting mechanisms, as well. It's an attempt to achieve Least Privilege.
Nesting the media adjacent to downloads is suggested via servarr.com as a way to allow atomic file moves as opposed to a more intensive/longer copy+paste action. Explained here.
Container Roles and Access to Files
Let's recognize four kinds of Media Server roles containers/apps:
- A Curator whose role is to enable the discovery and selection of Media by an End User. It then delivers a Work Order to the Acquirer. It also monitors the Media and ensures it is accurately described and and of desired quality.Ex. Sonarr, Radarr, Lidarr, Readarr, Ombi
- An Indexer whose role is to interpret how a Work Order should be completed. It figures out where the Media should come from while negotiating with each supplier. Ex. Jackett, Prowlaar
- An Acquirer whose role is to accept and execute a Work Order to retrieve a specific Media. It then delivers that Media to the Provider. Ex. qBitTorrent, Transmission
- A Provider whose role is to provide Media (movies, podcasts, etc) to end users. It is unconcerned with how the Media came to exist and isn't responsible for its quality or description. Ex. Emby, Plex, Jellyfin
Port Reservations
Ports are controlled through variables (ie. .env) to provide a central "fact check".
Optionals
Caddy and DuckDns.org
- If you do not use DuckDns.org and/or use another provider which needs a Caddy DNS module, alter
dockerfiles/caddy.dockerfileappropriately