docs: add scripts/README.md and scripts/CHANGELOG.md
- scripts/README.md: comprehensive docker-setup.sh documentation (CLI flags, installation steps, TLS modes, hub download, wizard, safety features) - scripts/CHANGELOG.md: version history from v1.0.0 to v5.0.0 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,39 @@
|
|||||||
|
# scripts/ — Changelog
|
||||||
|
|
||||||
|
## docker-setup.sh v5.0.0 (2026-02-20)
|
||||||
|
|
||||||
|
- **Hub Config Download:**
|
||||||
|
- Added `--hub-customer` and `--hub-password` CLI flags
|
||||||
|
- Downloads pre-configured `controller.yaml` from Felhom Hub (`GET /api/v1/config/{id}`)
|
||||||
|
- Extracts domain, email, CF tokens from downloaded YAML for subsequent setup steps
|
||||||
|
- Falls back to interactive wizard if download fails or credentials not provided
|
||||||
|
- Hub URL: `https://hub.felhom.eu` (configurable via `HUB_URL` variable)
|
||||||
|
|
||||||
|
## docker-setup.sh v4.0.0 (2026-02-19)
|
||||||
|
|
||||||
|
- Cloudflare Tunnel support: optional tunnel deployment when token provided in wizard
|
||||||
|
- Self-signed certificate generation: `--self-signed-cert` flag with CA + wildcard cert
|
||||||
|
- Three TLS modes: Let's Encrypt DNS-01, Let's Encrypt HTTP-01, Self-signed
|
||||||
|
- FileBrowser Quantum auto-discovers drive mounts from `/mnt/*/`
|
||||||
|
- System data path support in wizard and FileBrowser volumes
|
||||||
|
|
||||||
|
## docker-setup.sh v3.0.0 (2026-02-17)
|
||||||
|
|
||||||
|
- Interactive configuration wizard with 6 sections
|
||||||
|
- Static IP configuration supporting NetworkManager, systemd-networkd, ifupdown
|
||||||
|
- Traefik v3 reverse proxy with Let's Encrypt DNS-01 (Cloudflare)
|
||||||
|
- Controller deployment with privileged access for system management
|
||||||
|
- Docker shell aliases and helper tools (ctop, lazydocker)
|
||||||
|
|
||||||
|
## docker-setup.sh v2.0.0 (2026-02-14)
|
||||||
|
|
||||||
|
- Dry-run mode (`--dry-run`) for safe preview
|
||||||
|
- Bootstrap mode (`--bootstrap`) for fresh Debian without sudo
|
||||||
|
- Error trapping with diagnostic collection
|
||||||
|
- Docker daemon.json DNS fallback configuration
|
||||||
|
|
||||||
|
## docker-setup.sh v1.0.0 (2026-02-10)
|
||||||
|
|
||||||
|
- Initial release: Docker + Traefik + controller deployment
|
||||||
|
- CLI flag parsing with validation
|
||||||
|
- Basic configuration wizard
|
||||||
@@ -0,0 +1,197 @@
|
|||||||
|
# scripts/
|
||||||
|
|
||||||
|
Setup and maintenance scripts for Felhom homeserver deployments.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## docker-setup.sh
|
||||||
|
|
||||||
|
**Automated deployment script for Felhom customer nodes.**
|
||||||
|
|
||||||
|
Takes a fresh Debian 13 server and deploys a complete Felhom homeserver stack:
|
||||||
|
Docker, Traefik reverse proxy, Cloudflare Tunnel (optional), TLS certificates,
|
||||||
|
FileBrowser, and the felhom-controller dashboard.
|
||||||
|
|
||||||
|
**Version:** 5.0.0
|
||||||
|
|
||||||
|
### Quick start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Minimal — interactive wizard for all settings
|
||||||
|
sudo ./docker-setup.sh --domain example.com --email admin@example.com
|
||||||
|
|
||||||
|
# Full — Cloudflare DNS + static IP + pre-seeded customer
|
||||||
|
sudo ./docker-setup.sh \
|
||||||
|
--ip 192.168.0.50 \
|
||||||
|
--domain example.com \
|
||||||
|
--email admin@example.com \
|
||||||
|
--cf-token "your-cloudflare-api-token" \
|
||||||
|
--customer "customer-1"
|
||||||
|
|
||||||
|
# Hub mode — download pre-configured controller.yaml from Felhom Hub
|
||||||
|
sudo ./docker-setup.sh \
|
||||||
|
--domain example.com \
|
||||||
|
--email admin@example.com \
|
||||||
|
--hub-customer "customer-1" \
|
||||||
|
--hub-password "retrieval-password-from-hub"
|
||||||
|
```
|
||||||
|
|
||||||
|
### CLI flags
|
||||||
|
|
||||||
|
| Flag | Argument | Description | Default |
|
||||||
|
|------|----------|-------------|---------|
|
||||||
|
| `--bootstrap` | — | Install sudo on fresh Debian (run as root first) | — |
|
||||||
|
| `--ip` | ADDRESS | Static IP address (e.g., `192.168.0.50`) | DHCP |
|
||||||
|
| `--gateway` | ADDRESS | Gateway address | `192.168.0.1` |
|
||||||
|
| `--dns` | SERVERS | DNS servers, comma-separated | `1.1.1.1,8.8.8.8` |
|
||||||
|
| `--interface` | NAME | Network interface name | Auto-detect |
|
||||||
|
| `--domain` | DOMAIN | Base domain (pre-seeds wizard) | `homeserver.local` |
|
||||||
|
| `--email` | EMAIL | ACME email for Let's Encrypt | — |
|
||||||
|
| `--cf-token` | TOKEN | Cloudflare API token for DNS-01 challenge | — |
|
||||||
|
| `--customer` | ID | Customer identifier (pre-seeds wizard) | — |
|
||||||
|
| `--hub-customer` | ID | Download config from Hub: customer ID | — |
|
||||||
|
| `--hub-password` | PASSWORD | Download config from Hub: retrieval password | — |
|
||||||
|
| `--traefik-password` | PASSWORD | Traefik dashboard basicAuth password | Auto-generated |
|
||||||
|
| `--self-signed-cert` | — | Generate self-signed wildcard certificate | `false` |
|
||||||
|
| `--skip-filebrowser` | — | Skip FileBrowser installation | `false` |
|
||||||
|
| `--dry-run` | — | Show plan without making changes | `false` |
|
||||||
|
| `--debug` | — | Enable bash debug tracing (`set -x`) | `false` |
|
||||||
|
| `-h, --help` | — | Show help message | — |
|
||||||
|
|
||||||
|
### Installation steps
|
||||||
|
|
||||||
|
The script runs these steps in order:
|
||||||
|
|
||||||
|
| Step | Function | Description |
|
||||||
|
|------|----------|-------------|
|
||||||
|
| 1 | `install_base_packages()` | Install system packages: curl, git, htop, jq, openssl, apache2-utils, etc. |
|
||||||
|
| 2 | `configure_static_ip()` | Configure static IP (optional). Supports NetworkManager, systemd-networkd, ifupdown. |
|
||||||
|
| 3 | `install_docker()` | Install Docker CE + Compose plugin. GPG key, repo setup, daemon.json with DNS fallback, `traefik-public` network. |
|
||||||
|
| 4 | `install_traefik()` | Deploy Traefik v3.6.7 reverse proxy with configurable TLS (Let's Encrypt DNS-01/HTTP-01 or self-signed). |
|
||||||
|
| 4b | `install_cloudflare_tunnel()` | Deploy Cloudflare Tunnel (optional, only if tunnel token provided in wizard). |
|
||||||
|
| 5 | `generate_self_signed_cert()` | Generate self-signed CA + wildcard cert (optional, if `--self-signed-cert` flag set). |
|
||||||
|
| 6 | `run_config_wizard()` | Interactive wizard or Hub download. Generates `controller.yaml` with customer settings. |
|
||||||
|
| 7 | `install_filebrowser()` | Deploy FileBrowser Quantum with auto-discovered drive mounts (optional). |
|
||||||
|
| 8 | `install_controller()` | Deploy felhom-controller (privileged container with system access). |
|
||||||
|
| 9 | `install_tools_and_configure()` | Install ctop, lazydocker, Docker shell aliases. |
|
||||||
|
|
||||||
|
### TLS certificate modes
|
||||||
|
|
||||||
|
The script supports three mutually exclusive TLS modes:
|
||||||
|
|
||||||
|
1. **Let's Encrypt + Cloudflare DNS-01** (recommended)
|
||||||
|
- Requires: `--email` + `--cf-token`
|
||||||
|
- Works with Cloudflare Tunnel (no public port 80 needed)
|
||||||
|
- Automatic renewal via Traefik
|
||||||
|
|
||||||
|
2. **Let's Encrypt + HTTP-01**
|
||||||
|
- Requires: `--email` (no `--cf-token`)
|
||||||
|
- Requires port 80 publicly accessible
|
||||||
|
- Does NOT work with Cloudflare Tunnel
|
||||||
|
|
||||||
|
3. **Self-signed certificate**
|
||||||
|
- Requires: `--self-signed-cert`
|
||||||
|
- Generates 10-year wildcard cert with custom CA
|
||||||
|
- CA cert copied to user home for manual device import
|
||||||
|
|
||||||
|
### Hub download mode
|
||||||
|
|
||||||
|
When both `--hub-customer` and `--hub-password` are provided, the script downloads a
|
||||||
|
pre-configured `controller.yaml` from the Felhom Hub instead of running the interactive wizard:
|
||||||
|
|
||||||
|
```
|
||||||
|
GET https://hub.felhom.eu/api/v1/config/{customer_id}
|
||||||
|
Header: X-Retrieval-Password: {password}
|
||||||
|
```
|
||||||
|
|
||||||
|
On success:
|
||||||
|
- Saves downloaded YAML as `controller.yaml` (permissions 600)
|
||||||
|
- Extracts domain, email, CF tokens for use by subsequent setup steps (Traefik, Cloudflare Tunnel)
|
||||||
|
- Skips the interactive wizard entirely
|
||||||
|
|
||||||
|
On failure:
|
||||||
|
- Logs a warning with HTTP status code
|
||||||
|
- Falls back to the interactive wizard
|
||||||
|
|
||||||
|
Hub credentials are created in the Hub web UI at `https://hub.felhom.eu/configs`.
|
||||||
|
|
||||||
|
### Configuration wizard
|
||||||
|
|
||||||
|
When Hub download is not used, the interactive wizard prompts for:
|
||||||
|
|
||||||
|
| Section | Fields |
|
||||||
|
|---------|--------|
|
||||||
|
| Customer identity | ID, display name, domain, email |
|
||||||
|
| Infrastructure secrets | Cloudflare Tunnel token, CF API token |
|
||||||
|
| Paths | System data partition mount point |
|
||||||
|
| Dashboard password | bcrypt-hashed login password (optional) |
|
||||||
|
| Git sync | App catalog repo URL, username, token |
|
||||||
|
| Monitoring | 5x healthchecks.io ping UUIDs (heartbeat, system, DB dump, backup, integrity) |
|
||||||
|
|
||||||
|
Validation:
|
||||||
|
- Customer ID is required (cannot be empty or `demo-felhom`)
|
||||||
|
- Domain is required (cannot be `homeserver.local`)
|
||||||
|
|
||||||
|
### Output files
|
||||||
|
|
||||||
|
| Path | Description |
|
||||||
|
|------|-------------|
|
||||||
|
| `/opt/docker/felhom-controller/controller.yaml` | Controller configuration (perms 600) |
|
||||||
|
| `/opt/docker/felhom-controller/docker-compose.yml` | Controller container definition |
|
||||||
|
| `/opt/docker/traefik/traefik.yml` | Traefik static configuration |
|
||||||
|
| `/opt/docker/traefik/dynamic/dashboard.yml` | Traefik dashboard route |
|
||||||
|
| `/opt/docker/traefik/docker-compose.yml` | Traefik container definition |
|
||||||
|
| `/opt/docker/stacks/filebrowser/docker-compose.yml` | FileBrowser container definition |
|
||||||
|
| `/opt/docker/cloudflared/docker-compose.yml` | Cloudflare Tunnel definition (optional) |
|
||||||
|
| `/var/log/docker-setup.log` | Full installation log |
|
||||||
|
|
||||||
|
### Safety features
|
||||||
|
|
||||||
|
- **Error trapping:** `set -euo pipefail` + ERR trap with diagnostic collection
|
||||||
|
- **Dry-run mode:** Full preview without state changes
|
||||||
|
- **Input validation:** IP format, required fields, credential checks
|
||||||
|
- **Atomic writes:** Temp file + rename for sensitive config files
|
||||||
|
- **Permission hardening:** 600 for secrets, 644 for certificates
|
||||||
|
- **Idempotency:** Checks for existing installations, skips if already done
|
||||||
|
- **Docker fallback:** Falls back from Debian 13 (trixie) to 12 (bookworm) repo if needed
|
||||||
|
- **DNS verification:** Tests DNS resolution before proceeding
|
||||||
|
- **Health checks:** Verifies Docker daemon ready, containers running after each deploy
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- **OS:** Debian 13 (Trixie) — minimal support for other distros with warnings
|
||||||
|
- **Privileges:** Must run with `sudo`
|
||||||
|
- **Network:** Internet connection for package downloads and Docker image pulls
|
||||||
|
- **DNS:** Must resolve before script runs (verified via `getent hosts download.docker.com`)
|
||||||
|
|
||||||
|
### Bootstrap mode
|
||||||
|
|
||||||
|
On a fresh Debian install without sudo:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# As root — install sudo and configure user
|
||||||
|
./docker-setup.sh --bootstrap
|
||||||
|
|
||||||
|
# Then as regular user — full setup
|
||||||
|
sudo ./docker-setup.sh --domain example.com --email admin@example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### Shell aliases installed
|
||||||
|
|
||||||
|
After setup, these aliases are added to the user's `.bashrc`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dc='sudo docker compose'
|
||||||
|
dcu='sudo docker compose up -d'
|
||||||
|
dcd='sudo docker compose down'
|
||||||
|
dcl='sudo docker compose logs -f'
|
||||||
|
dps='sudo docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"'
|
||||||
|
dlogs='sudo docker logs -f'
|
||||||
|
dexec='sudo docker exec -it'
|
||||||
|
dprune='sudo docker system prune -af'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Helper tools installed
|
||||||
|
|
||||||
|
- **ctop** — Top-like interface for container metrics
|
||||||
|
- **lazydocker** — Terminal UI for Docker management
|
||||||
Reference in New Issue
Block a user