updated docs and readme to showcase playbooks

This commit is contained in:
rezayaghobi-dev
2026-07-25 21:05:29 +03:30
parent 4f2911df62
commit 99ce5e8667
4 changed files with 170 additions and 56 deletions

142
README.md
View File

@@ -5,71 +5,97 @@ A self-hosted homelab running on Docker Compose, built and maintained on an Ubun
![Docker](https://img.shields.io/badge/Docker-2496ED?style=flat&logo=docker&logoColor=white)
![Docker Compose](https://img.shields.io/badge/Docker_Compose-2496ED?style=flat&logo=docker&logoColor=white)
![Ubuntu](https://img.shields.io/badge/Ubuntu_Server-E95420?style=flat&logo=ubuntu&logoColor=white)
![Ansible](https://img.shields.io/badge/Ansible-EE0000?style=flat&logo=ansible&logoColor=white)
![Prometheus](https://img.shields.io/badge/Prometheus-E6522C?style=flat&logo=prometheus&logoColor=white)
![Grafana](https://img.shields.io/badge/Grafana-F46800?style=flat&logo=grafana&logoColor=white)
## Overview
This is a real, running homelab — not a demo. It's deployed on a home Ubuntu server and managed entirely through Docker Compose, with each service isolated in its own folder. Configs here are the actual files running in production, with all secrets, API keys, and runtime state stripped out and replaced with `.env.example` placeholders.
This is a real, running homelab — not a demo. It's deployed on a home Ubuntu server and managed entirely through Docker Compose, with each service isolated in its own folder, and updated through a shared Ansible role run via Semaphore. Configs here are the actual files running in production, with all secrets, API keys, and runtime state stripped out and replaced with `.env.example` placeholders.
## Services
| Service | Folder | Purpose |
|---|---|---|
| **Monitoring stack** | `monitoring-grafana-promethues-cadvisor-node-exporter/` | Prometheus for metrics collection, Grafana for dashboards, cAdvisor for per-container resource stats, node-exporter for host-level metrics |
| **Pi-hole** | `pihole/` | Network-wide DNS-level ad and tracker blocking |
| **Portainer** | `portainer/` | Web UI for managing and monitoring all Docker containers on the host |
| **DockScope** | `dockscope/` | 3D visual dashboard mapping containers, networks, and dependencies, with anomaly detection and crash diagnostics — see [DockScope](docs/DockScope.md) |
| **n8n** | `n8n/` | Workflow automation engine, backed by Postgres |
| **Samba** | `samba/` | Network file sharing across LAN devices |
| **Filebrowser** | `filebrowser/` | Web-based file manager for the server's storage |
| **Media stack** | `mediastack/` | Plex (media server), Sonarr/Radarr/Prowlarr (media automation and indexing), qBittorrent (download client) |
| **Minecraft** | `minecraft/` | Self-hosted game server |
| **Sentinel** | `sentinel/` | Disk health monitoring integrated with smartctl, dumps output to container logs |
| **smartctl** | `smartctl/` | Disk health monitoring (S.M.A.R.T. data) |
| **OpenHands** | `openhands/` | Self-hosted AI coding agent (OpenHands/agent-canvas) backed by Ollama — see [AI Coding Agent](docs/AI-Agent.md) |
| **Nginx Proxy Manager** | `nginx-proxy-manager/` | Reverse proxy giving every service a friendly `.home` hostname with locally-trusted HTTPS — see [Reverse Proxy](docs/Reverse-Proxy.md) |
| **Semaphore** | `semaphore/` | Self-hosted Ansible UI (alternative to AWX) — see [Semaphore Guide](docs/Semaphore.md) |
| **Monitoring stack** | `docker-compose/monitoring-grafana-promethues-cadvisor-node-exporter/` | Prometheus for metrics collection, Grafana for dashboards, cAdvisor for per-container resource stats, node-exporter for host-level metrics |
| **Pi-hole** | `docker-compose/pihole/` | Network-wide DNS-level ad and tracker blocking |
| **Portainer** | `docker-compose/portainer/` | Web UI for managing and monitoring all Docker containers on the host |
| **DockScope** | `docker-compose/dockscope/` | 3D visual dashboard mapping containers, networks, and dependencies, with anomaly detection and crash diagnostics — see [DockScope](docs/DockScope.md) |
| **n8n** | `docker-compose/n8n/` | Workflow automation engine, backed by Postgres |
| **Samba** | `docker-compose/samba/` | Network file sharing across LAN devices |
| **Filebrowser** | `docker-compose/filebrowser/` | Web-based file manager for the server's storage |
| **Media stack** | `docker-compose/mediastack/` | Plex (media server), Sonarr/Radarr/Prowlarr (media automation and indexing), qBittorrent (download client) |
| **Minecraft** | `docker-compose/minecraft/` | Self-hosted game server |
| **Sentinel** | `docker-compose/sentinel/` | Disk health monitoring integrated with smartctl, dumps output to container logs |
| **smartctl** | `docker-compose/smartctl/` | Disk health monitoring (S.M.A.R.T. data) |
| **OpenHands** | `docker-compose/openhands/` | Self-hosted AI coding agent (OpenHands/agent-canvas) backed by Ollama — see [AI Coding Agent](docs/AI-Agent.md) |
| **Nginx Proxy Manager** | `docker-compose/nginx-proxy-manager/` | Reverse proxy giving every service a friendly `.home` hostname with locally-trusted HTTPS — see [Reverse Proxy](docs/Reverse-Proxy.md) |
| **Semaphore** | `docker-compose/semaphore/` | Self-hosted Ansible UI (alternative to AWX) — see [Semaphore Guide](docs/Semaphore.md) |
| **Ansible playbooks** | `ansible/` | Shared update role (pull → recreate → health-check → prune) reused across every stack, run via Semaphore — see [Ansible Playbooks](docs/AnsiblePlaybooks.md) |
## Repository structure
```
homelab/
├── monitoring-grafana-promethues-cadvisor-node-exporter/
│ └── docker-compose.yml
├── pihole/
│ ├── docker-compose.yml
│ └── .env.example
├── portainer/
│ └── docker-compose.yml
├── dockscope/
│ └── docker-compose.yml
├── n8n/
│ ├── docker-compose.yaml
│ └── .env.example
├── samba/
│ ├── docker-compose.yml
│ └── .env.example
├── filebrowser/
│ └── docker-compose.yml
├── mediastack/
│ ├── plex/docker-compose.yml
│ ├── sonarr/docker-compose.yml
│ ├── radarr/docker-compose.yml
│ ├── prowlarr/docker-compose.yml
│ ├── whisparr/docker-compose.yml
│ └── download-client-qbittorent/docker-compose.yml
├── minecraft/
│ └── docker-compose.yml
├── sentinel/
│ └── docker-compose.yml
├── smartctl/
│ └── docker-compose.yml
├── openhands/
│ └── docker-compose.yaml
├── nginx-proxy-manager/
│ └── docker-compose.yaml
├── semaphore/
│ ├── docker-compose.yml
├── docker-compose/
│ ├── monitoring-grafana-promethues-cadvisor-node-exporter/
│ │ └── docker-compose.yml
│ ├── pihole/
│ │ ├── docker-compose.yml
│ │ └── .env.example
│ ├── portainer/
│ │ └── docker-compose.yml
│ ├── dockscope/
│ │ └── docker-compose.yml
│ ├── n8n/
│ │ ├── docker-compose.yaml
│ │ └── .env.example
│ ├── samba/
│ │ ├── docker-compose.yml
│ │ └── .env.example
│ ├── filebrowser/
│ │ └── docker-compose.yml
│ ├── mediastack/
│ │ ├── plex/docker-compose.yml
│ │ ├── sonarr/docker-compose.yml
│ │ ├── radarr/docker-compose.yml
│ │ ├── prowlarr/docker-compose.yml
│ │ ├── whisparr/docker-compose.yml
│ │ └── download-client-qbittorent/docker-compose.yml
│ ├── minecraft/
│ │ └── docker-compose.yml
│ ├── sentinel/
│ │ └── docker-compose.yml
│ ├── smartctl/
│ │ └── docker-compose.yml
│ ├── openhands/
│ │ └── docker-compose.yaml
│ ├── nginx-proxy-manager/
│ │ └── docker-compose.yaml
│ └── semaphore/
│ ├── docker-compose.yml
│ └── README.md
├── ansible/
│ └── playbooks/
│ ├── roles/
│ │ └── docker_compose_update/
│ │ └── tasks/main.yml
│ ├── update-filebrowser.yml
│ ├── update-n8n.yml
│ ├── update-npm.yml
│ ├── update-pihole.yml
│ ├── update-plex.yml
│ ├── update-portainer.yml
│ ├── update-prowlarr.yml
│ ├── update-radarr.yml
│ ├── update-samba.yml
│ ├── update-sentinel.yml
│ ├── update-smartctl.yml
│ ├── update-sonarr.yml
│ ├── update-whisparr.yml
│ ├── update-agent-canvas.yml
│ ├── update-grafana.yml
│ └── ping.yml
├── docs/
│ ├── Home.md
│ ├── Architecture-and-Hardware.md
@@ -81,8 +107,9 @@ homelab/
│ ├── AI-Agent.md
│ ├── Reverse-Proxy.md
│ ├── Lessons-Learned.md
│ ├── Semaphore.md
│ ├── Semaphore.md
│ ├── DockScope.md
│ ├── AnsiblePlaybooks.md
│ └── images/
└── .gitignore
```
@@ -92,17 +119,21 @@ homelab/
Each folder is a standalone Compose stack:
```bash
cd pihole
cd docker-compose/pihole
cp .env.example .env # fill in real values
docker compose up -d
```
## Updating a service
Rather than pulling and recreating manually, every stack has a matching Ansible playbook that pulls the latest images, recreates containers, verifies they're healthy, and prunes unused images — run through Semaphore's web UI. See [Ansible Playbooks](docs/AnsiblePlaybooks.md) for details on how the shared role works.
## Security notes
- All `.env` files, runtime config directories, and databases are excluded via `.gitignore` — only deployment definitions (`docker-compose.yml`) and `.env.example` placeholders are tracked.
- Passwords referenced in compose files are injected via environment variables, never hardcoded.
- The AI coding agent (`openhands/`) currently uses a third-party API aggregator as its LLM backend — see [AI Coding Agent](docs/AI-Agent.md) for details and caveats. It has no access to the Docker socket or other containers on the host.
- **DockScope** (`dockscope/`) mounts `/var/run/docker.sock`, the same as Portainer — this grants it effectively root-equivalent access to the Docker host, and it currently has no built-in authentication on its web UI, so it's kept LAN-only and not exposed through the reverse proxy. See [DockScope](docs/DockScope.md).
- The AI coding agent (`docker-compose/openhands/`) currently uses a third-party API aggregator as its LLM backend — see [AI Coding Agent](docs/AI-Agent.md) for details and caveats. It has no access to the Docker socket or other containers on the host.
- **DockScope** (`docker-compose/dockscope/`) mounts `/var/run/docker.sock`, the same as Portainer — this grants it effectively root-equivalent access to the Docker host, and it currently has no built-in authentication on its web UI, so it's kept LAN-only and not exposed through the reverse proxy. See [DockScope](docs/DockScope.md).
## Lessons learned
@@ -111,6 +142,7 @@ docker compose up -d
- Centralized monitoring (Prometheus + Grafana + cAdvisor + node-exporter) made it possible to actually see resource usage per container, which mattered a lot on lower-spec hardware.
- Free-tier cloud AI APIs enforce regional access restrictions automatically — worth checking a provider's terms before building around "free tier" as an assumption. See [AI Coding Agent](docs/AI-Agent.md).
- Wildcard TLS certs (`*.home`) are rejected by browsers on single-label local domains — certificates for local reverse proxies need explicit hostnames listed instead. See [Reverse Proxy](docs/Reverse-Proxy.md).
- Grouping all Compose stacks under one `docker-compose/` folder (rather than flat at repo root) kept the structure readable once Ansible playbooks were added as a sibling — a flat repo mixing deployment configs and automation code got confusing fast.
## Roadmap