# Homelab ## Prerequisites - **Docker** and **Docker Compose** - Host paths used by the stacks: - `/srv/homelab` - `/srv/media` - `/backup` ## Setup ### 1. Media dirs ```bash sudo mkdir -p /srv/media/{movies,shows,downloads,immich} sudo chown -R 1000:1000 /srv/media ``` ### 2. Monitoring permissions ```bash sudo mkdir -p /srv/homelab/data/monitoring/{prometheus,loki,grafana,alloy} sudo chown -R 65534:65534 /srv/homelab/data/monitoring/prometheus sudo chown -R 10001:10001 /srv/homelab/data/monitoring/loki sudo chown -R 472:472 /srv/homelab/data/monitoring/grafana sudo chown -R 10001:10001 /srv/homelab/data/monitoring/alloy ``` ### 3. Env - **Glance:** `stacks/monitoring/glance.env` - **Immich:** `stacks/media/immich.env` ## Deploying From the repo root (`/srv/homelab`): | Stack | Command | |------------|---------| | **Media** | `docker compose -f stacks/media/compose.yaml up -d` | | **Monitoring** | `docker compose -f stacks/monitoring/compose.yaml up -d` | | **Storage** | `docker compose -f stacks/storage/compose.yaml up -d` | To update images: ```bash docker compose -f stacks/media/compose.yaml pull docker compose -f stacks/media/compose.yaml up -d ``` To stop a stack: ```bash docker compose -f stacks/media/compose.yaml down ``` ## Ports | Service | Port(s) | Stack | |---------------|----------------------|-----------| | **Media** | | | | Sonarr | 8989 | media | | Radarr | 7878 | media | | Lidarr | 8686 | media | | Prowlarr | 9696 | media | | qBittorrent | 8081, 6881 (tcp/udp) | media | | Jellyfin | 8096 | media | | Immich | 2283 | media | | Navidrome | 4533 | media | | Seer | 5055 | media | | **Monitoring**| | | | Grafana | 3034 | monitoring| | Prometheus | 9094 | monitoring| | Loki | 3100 | monitoring| | Node Exporter | 9100 | monitoring| | Alloy | 12345 | monitoring| | cAdvisor | 8088 | monitoring| | Glance | 9090 | monitoring| | Portainer | 9443, 8000 | monitoring| | **Storage** | | | | Gitea | 3000, 222 | storage | | Copyparty | 3923 | storage | ## Backup Backups use [Restic](https://restic.net/). The script backs up `/srv/homelab` (including `data/`), `/etc/caddy/Caddyfile`, and `/etc/unbound/unbound.conf`. It **stops all Docker stacks** before backup for consistent data, then starts them again—run it manually when you can afford a few minutes of downtime. ### One-time setup 1. Install restic (e.g. `pacman -S restic` or from [restic.net](https://restic.net/)). 2. Copy the env example and set repository and password: ```bash cp scripts/restic-backup.env.example scripts/restic-backup.env # Edit scripts/restic-backup.env: set RESTIC_REPOSITORY and RESTIC_PASSWORD ``` Examples for `RESTIC_REPOSITORY`: - Local: `RESTIC_REPOSITORY=/backup/restic` - SFTP: `RESTIC_REPOSITORY=sftp:user@backup-host:/restic` - S3: `RESTIC_REPOSITORY=s3:s3.amazonaws.com/bucket-name` 3. Initialize the repo (once): ```bash export RESTIC_PASSWORD='your-password' restic -r /backup/restic init # use your actual repo path ``` ### Create a backup From the repo root, run: ```bash sudo ./scripts/restic-backup.sh ``` Stacks are stopped, then the backup runs, then they are started again. A failed backup still triggers the start so the homelab comes back up. ### Inspect backups List snapshots (IDs and timestamps): ```bash source scripts/restic-backup.env sudo restic snapshots -r $RESTIC_REPOSITORY ``` List files in a snapshot (e.g. latest or by ID): ```bash restic ls latest -r $RESTIC_REPOSITORY restic ls -r $RESTIC_REPOSITORY ``` Browse a path inside a snapshot: ```bash restic ls latest -r $RESTIC_REPOSITORY /srv/homelab/config ``` ### See diffs between backups Compare two snapshots (added, changed, removed files and content diff): ```bash restic diff -r $RESTIC_REPOSITORY ``` ### Restore Restore the latest snapshot into a directory (does not overwrite the repo; use a separate target dir): ```bash restic restore latest --target /tmp/restore -r $RESTIC_REPOSITORY ``` Restore a specific snapshot or path: ```bash restic restore --target /tmp/restore -r $RESTIC_REPOSITORY restic restore latest --path /etc/caddy --target /tmp/restore -r $RESTIC_REPOSITORY ``` After restore, fix ownership on `data/` if needed (see [Monitoring permissions](#2-monitoring-permissions)).