A personal project to provide security, privacy, and data-ownership for my home.
Includes:
The following apps / technologies are grouped into ./services/
.
Service | Note | Includes |
---|---|---|
adblock-and-dns | Pihole Unbound | |
change-detect | ChangeDetection.io Chrome | |
dashboard | Homepage | |
downloads | qBitTorrent Gluetun Radarr Sonarr Lidarr Prowlaar + PodGrab | |
events | Rallly PostGres | |
gloomhaven | Gloomhaven Secretariat | |
infra | Required | docker socket proxy |
image-board | Pinry | |
media-request | Jellyseerr | |
media-streaming | Jellyfin | |
monitor | Dozzle Diun Scrutiny Speedtest Tracker Uptime Kuma | |
paperless | Paperless-ngx PostGres | |
public | Reverse Proxy and DDNS | Caddy DuckDNS |
recipes | Tandoor Recipes PostGres | |
security | Run this if you're running public |
CrowdSec + Endlessh |
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.
.env
file from the root directory (/opt/docker/homelab-docker/.env). This simplifies maintenance as some variables are used by multiple Services. This is accomplished via symlink..env
. See or execute ./scripts/run-each-update.sh
cd ./services/infra
docker compose up -d
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.
WIP
Recommendations via multiple docker files, Where to Put Docker Compose, TRaSH Guides
├── /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/ (SAMBA shared r/w for ingestion)
│ ├── podcasts/
│ └── tv/
└── media/
├── audiobooks/
├── music/
├── pictures/
├── podcasts/
├── movies/
└── tv/
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
TBD - this may vary based on your existing file system, user provisions, and/or usage of mergerfs or similar tools.
Recursively own the /mnt/storage directory
chown -R $USER:docker /mnt/storage
(the docker
group is available after Docker installation steps)
chmod -R a=,a+rX,u+w,g+w /mnt/storage
/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:
/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.
/mnt/storage/downloads/movies
/mnt/storage/media/movies
This structure helps achieve Least Privilege by separating concerns as efficiently as possible. Clear organization can also help with backup prioritization.
Examples:
/mnt/storage/downloads/
: qBittorrent should only have access to this directory./mnt/storage/
: Radarr has broader access, which allows it to organize files in downloads into media/mnt/storage/media/movies
: Jellyfin has very specific access to playback-ready movies, but not other media such as PodcastsNesting 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. Importantly, I configure these services to hardlink finished downloads - this preserves seeding ability while having no effect on storage consumption.
Let's recognize four kinds of Media Server roles containers/apps:
Ports are controlled through variables (ie. .env
) to provide a central "fact check".
dockerfiles/caddy.dockerfile
appropriately