168 lines
4.8 KiB
Markdown
168 lines
4.8 KiB
Markdown
# 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 <snapshot-id>
|
|
```
|
|
|
|
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 <older-snapshot-id> <newer-snapshot-id> -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 <snapshot-id> --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)).
|