Restructure documentation as docs/ folder with working links

This commit is contained in:
rezayaghobi-dev
2026-07-11 16:04:32 +03:30
parent 742aeeb664
commit 36f1dbdf03
16 changed files with 8 additions and 18 deletions

View File

@@ -0,0 +1,23 @@
# Architecture and Hardware
## Hardware
The homelab runs on a repurposed always-on Ubuntu Server box — modest specs by design, which shaped a lot of the decisions documented across this wiki (lightweight images, careful resource limits, monitoring everything so problems show up before they cause outages).
| Component | Spec |
|---|---|
| OS | Ubuntu Server |
| Orchestration | Docker + Docker Compose |
| Management UI | Portainer |
| Storage | Mixed SSD + HDD, monitored via Hard Disk Sentinel |
## Design principles
1. **One Compose stack per service.** Each service lives in its own folder with its own `docker-compose.yml`, instead of one giant file. Easier to update, restart, or debug a single service without touching the rest.
2. **Monitor everything.** Prometheus + Grafana + cAdvisor + node-exporter run from day one, not bolted on later — resource pressure on modest hardware shows up fast, and having metrics from the start made it possible to catch it.
3. **Secrets stay out of git.** Every service that needs credentials uses a `.env` file (gitignored) with a matching `.env.example` committed as a template.
4. **DNS-level filtering at the network edge.** Pi-hole sits in front of all DNS traffic rather than relying on per-device ad blockers.
## Network
All services communicate over Docker's internal bridge networks, with only the ports that need external access published to the host. See [Network Services](Network-Services.md) for details on Pi-hole and Portainer specifically.

28
docs/Home.md Normal file
View File

@@ -0,0 +1,28 @@
# Homelab Wiki
Documentation for a self-hosted homelab running entirely on Docker Compose. This wiki covers the *why* behind each service, how they're configured, and what I learned running them — the repo itself has the raw `docker-compose.yml` files.
## Contents
- [Architecture and Hardware](Architecture-and-Hardware.md)
- [Monitoring Stack](Monitoring-Stack.md)
- [Network Services](Network-Services.md)
- [Media Automation](Media-Automation.md)
- [Workflow Automation](Workflow-Automation.md)
- [Storage Health](Storage-Health.md)
- [Lessons Learned](Lessons-Learned.md)
## At a glance
| | |
|---|---|
| **Host** | Ubuntu Server |
| **Orchestration** | Docker Compose, one stack per service |
| **Management** | Portainer |
| **Monitoring** | Prometheus + Grafana + cAdvisor + node-exporter |
| **Network** | Pi-hole (DNS filtering), Samba (file sharing) |
| **Automation** | n8n |
| **Media** | Plex + Sonarr/Radarr/Prowlarr + qBittorrent |
| **Disk health** | Hard Disk Sentinel |
This is a running system, not a demo — screenshots throughout this wiki are from the live dashboards.

25
docs/Lessons-Learned.md Normal file
View File

@@ -0,0 +1,25 @@
# Lessons Learned
Things that weren't obvious until running this in practice.
## Secrets hide in more places than `.env` files
The first pass at redacting this repo before publishing only grepped for text patterns like `password` and `token`. That missed real secrets sitting in `config/` directories — a JWT signing key in Filebrowser's `settings.json`, API keys in the *arr apps' `config.xml` files. The fix was to gitignore entire `config/` and `data/` directories by convention, rather than trying to catch every secret individually with a text search.
## Splitting Compose stacks per service pays off
One Compose file per service (instead of one big file for everything) made it possible to update, restart, or debug a single service without touching the rest of the stack — and made the git history for this repo readable, since each commit maps to one logical piece of infrastructure.
## Monitoring from day one, not after something breaks
Standing up Prometheus + Grafana + cAdvisor + node-exporter early, before anything went wrong, meant resource pressure showed up on a dashboard instead of as an unexplained outage. On modest hardware this matters more, not less.
## Disk health monitoring is cheap insurance
Hard Disk Sentinel running continuously catches degrading drives via S.M.A.R.T. data well before failure — reallocated sectors and rising temperatures are visible weeks or months ahead of an actual crash.
## What's next
- Self-hosted Gitea for private repos and CI runners
- Automated deployment via Watchtower on new image pushes
- Alerting rules on top of the existing Prometheus/Grafana setup, not just dashboards

17
docs/Media-Automation.md Normal file
View File

@@ -0,0 +1,17 @@
# Media Automation
A self-hosted media stack: Plex serves the library, while Sonarr, Radarr, and Prowlarr handle automated indexing and library management, backed by qBittorrent as the download client.
![Plex dashboard](images/plex-dashboard.png)
## Stack
| Service | Role |
|---|---|
| Plex | Media server and streaming frontend |
| Sonarr | TV library automation |
| Radarr | Movie library automation |
| Prowlarr | Indexer management, shared across the *arr apps |
| qBittorrent | Download client |
Each runs as its own Compose stack under `mediastack/`, so any one service can be updated or restarted independently.

26
docs/Monitoring-Stack.md Normal file
View File

@@ -0,0 +1,26 @@
# Monitoring Stack
Prometheus, Grafana, cAdvisor, and node-exporter running together give full visibility into both the host and every container on it — essential on modest hardware where knowing what's consuming resources matters.
## Components
- **Prometheus** — scrapes and stores time-series metrics from every target below
- **node-exporter** — exposes host-level metrics (CPU, memory, disk, network)
- **cAdvisor** — exposes per-container resource usage
- **Grafana** — dashboards on top of Prometheus data
## Prometheus targets
All scrape targets healthy and reporting:
![Prometheus targets](images/prometheus-targets.png)
## Grafana: Node Exporter Full dashboard
Host-level metrics — CPU, memory, swap, disk, and network — over a rolling 24-hour window:
![Grafana Node Exporter dashboard](images/grafana-node-exporter.png)
## Why this matters
On a lower-spec host, resource headroom is limited. Having per-container and host-level metrics from day one means a runaway container or a creeping memory leak shows up on a dashboard before it takes the box down — instead of finding out from an outage.

17
docs/Network-Services.md Normal file
View File

@@ -0,0 +1,17 @@
# Network Services
## Pi-hole — network-wide DNS filtering
Pi-hole intercepts DNS for every device on the network, blocking ads and trackers at the DNS level instead of relying on per-browser extensions. Currently filtering roughly 20% of all queries against an active blocklist:
![Pi-hole dashboard](images/pihole-dashboard.png)
## Portainer — container management
A web UI for the full Docker environment: all containers, their health status, images, and published ports in one place. Useful both for day-to-day management and as a quick way to eyeball the state of the whole stack:
![Portainer container list](images/portainer-containers.png)
## Samba
Provides LAN-accessible file shares from the server's storage — used for moving files between devices on the network without a cloud intermediary.

13
docs/Storage-Health.md Normal file
View File

@@ -0,0 +1,13 @@
# Storage Health
Disks fail silently until they don't. Hard Disk Sentinel runs continuously to surface S.M.A.R.T. data — temperature, reallocated sectors, estimated remaining lifetime — before a drive fails outright rather than after.
![Hard Disk Sentinel report](images/storage-health-hdsentinel.png)
## What this catches
- Bad sector counts and whether they've been reallocated to spare area
- Temperature trends over the drive's lifetime
- An estimated health percentage and remaining lifetime, so a degrading drive can be replaced proactively instead of discovered after data loss
Identifying details (hostname, MAC address, disk serial number) are redacted from the screenshot above before publishing.

View File

@@ -0,0 +1,11 @@
# Workflow Automation
n8n runs self-hosted (backed by its own Postgres instance) for building automated workflows — connecting APIs, scheduling tasks, and chaining actions without needing separate scripts for each one.
![n8n workflow editor](images/n8n-workflow.png)
> **Note:** the workflow shown above is a community template being explored in the editor. _Replace this section with a description of a workflow you've actually built or customized — what it automates, what triggers it, and why you built it. A specific, real example is far more convincing here than a generic one._
## Why self-hosted n8n
Cloud automation platforms usually cap free usage or require a subscription for private workflows. Running n8n on the homelab keeps workflows private, removes execution limits, and integrates naturally with the rest of the self-hosted stack.

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB