247 lines
7.1 KiB
Markdown
247 lines
7.1 KiB
Markdown
# 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`.
|