Initial homelab infrastructure

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-02-13 19:41:46 +02:00
co-authored by Cursor
commit 5014d55d62
31 changed files with 1594 additions and 0 deletions
+246
View File
@@ -0,0 +1,246 @@
# Homelab Additions Plan: Kuma, Watchtower, Drone CI, CUPS Printer
## Overview
Add four new capabilities to the homelab:
1. **Uptime Kuma** Monitor service availability (HTTP, ping, etc.)
2. **Watchtower** Auto-update container images
3. **Drone CI** CI/CD for Gitea repos (server + Docker runner)
4. **CUPS** USB printer sharing for remote printing
---
## 1. Uptime Kuma
- **Image:** `louislam/uptime-kuma:1`
- **Port:** 3001
- **Data:** `./uptime-kuma:/app/data`
- **Traefik:** `kuma.zea.lt` with basic auth (same as other admin services)
- **Optional:** Mount `/var/run/docker.sock` for container monitoring
---
## 2. Watchtower
**Note:** Watchtower [is no longer maintained](https://github.com/containrrr/watchtower/discussions/2135). Alternatives:
- **WUD (What's Up Docker)** Web UI, manual/controlled updates, notifications
- **Diun** Notifications only (you decide when to update)
If you still want Watchtower for automatic updates, it works but may not receive future fixes.
- **Image:** `containrrr/watchtower`
- **Config:** Mount `/var/run/docker.sock`, run with `--schedule "0 0 4 * * *"` (daily at 4 AM) or `--interval 86400`
- **Optional:** `WATCHTOWER_CLEANUP=true` to remove old images
- **Label:** Add `com.centurylinklabs.watchtower.enable=false` to services you want to exclude (e.g. Traefik, WireGuard)
---
## 3. Drone CI
Requires **Gitea OAuth app** (manual step before starting Drone):
1. In Gitea: **Settings → Applications → Create OAuth2 Application**
2. **Application Name:** Drone
3. **Redirect URI:** `https://drone.zea.lt/login`
4. **Confidential Client:** checked
5. Save and copy **Client ID** and **Client Secret**
Components:
### Drone Server
- **Image:** `drone/drone:2`
- **Database:** SQLite in `/data` (simplest for homelab)
- **Env:** `DRONE_GITEA_*`, `DRONE_RPC_SECRET`, `DRONE_SERVER_HOST`, `DRONE_SERVER_PROTO`
- **Traefik:** `drone.zea.lt`
### Drone Docker Runner
- **Image:** `drone/drone-runner-docker:1`
- **Volume:** `/var/run/docker.sock`
- **Env:** `DRONE_RPC_HOST=drone`, `DRONE_RPC_PROTO=http`, `DRONE_RPC_SECRET=<same as server>`
- **Network:** `homelab` (to reach Gitea, Registry)
**Critical:** `DRONE_GITEA_SERVER` must be reachable from the Drone server. Use `https://git.zea.lt` (external URL) for OAuth; internal `http://gitea:3000` can cause callback issues when Gitea redirects.
---
## 4. CUPS (USB Printer via Docker)
- **Image:** `infra7/cups:latest` (supports arm64 for Raspberry Pi)
- **Device:** `--device /dev/bus/usb`
- **Ports:** `631:631` (IPP + web admin)
- **Env:** `CUPSADMIN`, `CUPSPASSWORD` (or Docker secrets)
- **Volume:** `./cups/config:/etc/cups` for persistence
- **Traefik:** `print.zea.lt` for web admin (optional)
**Remote printing:**
- Clients add printer: `ipp://YOUR_SERVER_IP:631/printers/<printer-name>`
- Or via `print.zea.lt` if you proxy IPP (less common)
**USB setup:**
1. Plug in printer
2. Run `lsusb` on host to verify
3. Ensure Docker can access `/dev/bus/usb` (permissions)
4. Open `http://YOUR_SERVER_IP:631` or `https://print.zea.lt` and add printer
---
## DNS Updates
Add to `pihole/etc-dnsmasq.d/02-custom.conf`:
```
address=/kuma.zea.lt/YOUR_SERVER_IP
address=/drone.zea.lt/YOUR_SERVER_IP
address=/print.zea.lt/YOUR_SERVER_IP
```
---
## Docker Compose Additions (draft)
```yaml
### 📊 Uptime Kuma ###
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma
restart: always
volumes:
- ./uptime-kuma:/app/data
- /var/run/docker.sock:/var/run/docker.sock # optional: monitor containers
networks:
- homelab
labels:
- "traefik.enable=true"
- "traefik.http.routers.kuma.rule=Host(`kuma.zea.lt`)"
- "traefik.http.routers.kuma.entrypoints=websecure"
- "traefik.http.routers.kuma.tls.certresolver=leresolver"
- "traefik.http.routers.kuma.middlewares=auth"
- "traefik.http.services.kuma.loadbalancer.server.port=3001"
### 🔄 Watchtower ###
watchtower:
image: containrrr/watchtower:latest
container_name: watchtower
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WATCHTOWER_SCHEDULE=0 0 4 * * *
- WATCHTOWER_CLEANUP=true
networks:
- homelab
### 🚀 Drone CI ###
drone-server:
image: drone/drone:2
container_name: drone
restart: always
environment:
- DRONE_GITEA_SERVER=https://git.zea.lt
- DRONE_GITEA_CLIENT_ID=${DRONE_GITEA_CLIENT_ID}
- DRONE_GITEA_CLIENT_SECRET=${DRONE_GITEA_CLIENT_SECRET}
- DRONE_RPC_SECRET=${DRONE_RPC_SECRET}
- DRONE_SERVER_HOST=drone.zea.lt
- DRONE_SERVER_PROTO=https
- DRONE_USER_CREATE=username:YOUR_GITEA_USER,admin:true # first admin
volumes:
- ./drone:/data
networks:
- homelab
labels:
- "traefik.enable=true"
- "traefik.http.routers.drone.rule=Host(`drone.zea.lt`)"
- "traefik.http.routers.drone.entrypoints=websecure"
- "traefik.http.routers.drone.tls.certresolver=leresolver"
- "traefik.http.routers.drone.middlewares=auth"
- "traefik.http.services.drone.loadbalancer.server.port=80"
drone-runner:
image: drone/drone-runner-docker:1
container_name: drone-runner
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- DRONE_RPC_HOST=drone
- DRONE_RPC_PROTO=http
- DRONE_RPC_SECRET=${DRONE_RPC_SECRET}
- DRONE_RUNNER_CAPACITY=2
networks:
- homelab
### 🖨️ CUPS Printer Server ###
cups:
image: infra7/cups:latest
container_name: cups
restart: always
ulimits:
nofile:
soft: 65536
hard: 65536
devices:
- /dev/bus/usb:/dev/bus/usb
environment:
- TZ=Europe/London
- CUPSADMIN=${CUPSADMIN:-admin}
- CUPSPASSWORD=${CUPSPASSWORD}
volumes:
- ./cups/config:/etc/cups
ports:
- "631:631"
networks:
- homelab
labels:
- "traefik.enable=true"
- "traefik.http.routers.print.rule=Host(`print.zea.lt`)"
- "traefik.http.routers.print.entrypoints=websecure"
- "traefik.http.routers.print.tls.certresolver=leresolver"
- "traefik.http.services.print.loadbalancer.server.port=631"
```
---
## .env Additions
```
# Drone CI (create OAuth app in Gitea first)
DRONE_GITEA_CLIENT_ID=your-client-id
DRONE_GITEA_CLIENT_SECRET=your-client-secret
DRONE_RPC_SECRET=<openssl rand -hex 16>
# CUPS printer admin
CUPSADMIN=admin
CUPSPASSWORD=your-secure-password
```
---
## Implementation Order
1. Add DNS entries for `kuma.zea.lt`, `drone.zea.lt`, `print.zea.lt`
2. Create directories: `mkdir -p uptime-kuma drone cups/config`
3. Add services to `docker-compose.yml`
4. Add secrets to `.env`
5. Create Gitea OAuth app
6. `docker compose up -d` for new services
7. Plug in USB printer, access CUPS at `https://print.zea.lt` or `:631`, add printer
8. Open Drone at `https://drone.zea.lt`, activate repos
9. Configure Uptime Kuma monitors for your services
---
## Watchtower Exclusions (optional)
To prevent Watchtower from updating critical services (Traefik, WireGuard), add:
```yaml
labels:
- "com.centurylinklabs.watchtower.enable=false"
```
To services: `traefik`, `wireguard`, optionally `pihole`.