Bootstrap CHELSTY runtime stack
This commit is contained in:
parent
cfd1951fcb
commit
81bce00bf3
60
docs/chelsty-runtime.md
Normal file
60
docs/chelsty-runtime.md
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
# CHELSTY Runtime
|
||||||
|
|
||||||
|
This document describes the runtime environment and deployment flow for CHELSTY, an offline-capable home automation edge node.
|
||||||
|
|
||||||
|
## Runtime Layout
|
||||||
|
|
||||||
|
The CHELSTY runtime is located at `/opt/homelab`.
|
||||||
|
|
||||||
|
- `/opt/homelab/config/`: Service-specific configurations and compose overrides.
|
||||||
|
- `/opt/homelab/data/`: Persistent data for services.
|
||||||
|
- `/opt/homelab/logs/`: Service logs.
|
||||||
|
|
||||||
|
### Key Service Locations
|
||||||
|
- **Mosquitto**: `/opt/homelab/config/mosquitto/`
|
||||||
|
- **Zigbee2MQTT**: `/opt/homelab/config/zigbee2mqtt/`
|
||||||
|
|
||||||
|
## SLZB-06U Integration
|
||||||
|
|
||||||
|
CHELSTY uses a SMLIGHT SLZB-06U Zigbee coordinator connected via Ethernet/TCP.
|
||||||
|
|
||||||
|
- **Coordinator IP**: 192.168.1.105
|
||||||
|
- **Port**: 6638
|
||||||
|
- **Protocol**: TCP (ezsp adapter)
|
||||||
|
|
||||||
|
Zigbee2MQTT is configured to connect to this coordinator over the local network.
|
||||||
|
|
||||||
|
## Offline & LTE Assumptions
|
||||||
|
|
||||||
|
- **WAN Resilience**: All core automation (Zigbee, MQTT) runs locally on CHELSTY.
|
||||||
|
- **Connectivity**: LTE provides intermittent uplink for remote management and Tailscale access.
|
||||||
|
- **Home Assistant**: Runs in a separate VM, connecting to the Mosquitto broker on CHELSTY.
|
||||||
|
|
||||||
|
## Deployment Flow
|
||||||
|
|
||||||
|
1. **Initial Bootstrap**:
|
||||||
|
Run the bootstrap script on the CHELSTY node:
|
||||||
|
```bash
|
||||||
|
./scripts/bootstrap/chelsty-runtime.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Manual Configuration**:
|
||||||
|
- Edit `/opt/homelab/config/zigbee2mqtt/.env` with MQTT credentials.
|
||||||
|
- Add Mosquitto user:
|
||||||
|
```bash
|
||||||
|
sudo mosquitto_passwd -b /opt/homelab/data/mosquitto/config/password.txt <user> <password>
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Service Deployment**:
|
||||||
|
Use the staged deployment runtime:
|
||||||
|
```bash
|
||||||
|
./scripts/deploy/deploy-node.sh chelsty
|
||||||
|
```
|
||||||
|
|
||||||
|
## Recovery Procedure
|
||||||
|
|
||||||
|
In case of runtime failure:
|
||||||
|
1. Verify Docker and Compose plugin: `docker compose version`
|
||||||
|
2. Re-run bootstrap script to ensure directory structure and basic configs.
|
||||||
|
3. Check Mosquitto logs: `tail -f /opt/homelab/data/mosquitto/log/mosquitto.log`
|
||||||
|
4. Verify SLZB-06U reachability: `ping 192.168.1.105`
|
||||||
11
hosts/chelsty/runtime/mosquitto/docker-compose.override.yml
Normal file
11
hosts/chelsty/runtime/mosquitto/docker-compose.override.yml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
services:
|
||||||
|
mosquitto:
|
||||||
|
volumes:
|
||||||
|
- ./mosquitto.conf:/mosquitto/config/mosquitto.conf:ro
|
||||||
|
- /opt/homelab/data/mosquitto/config/password.txt:/mosquitto/config/password.txt:ro
|
||||||
|
# Healthcheck compatibility
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "mosquitto_sub -t '$SYS/broker/version' -C 1 || exit 1"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
13
hosts/chelsty/runtime/mosquitto/mosquitto.conf
Normal file
13
hosts/chelsty/runtime/mosquitto/mosquitto.conf
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
persistence true
|
||||||
|
persistence_location /mosquitto/data/
|
||||||
|
log_dest file /mosquitto/log/mosquitto.log
|
||||||
|
log_dest stdout
|
||||||
|
|
||||||
|
# Default listener
|
||||||
|
listener 1883
|
||||||
|
allow_anonymous false
|
||||||
|
password_file /mosquitto/config/password.txt
|
||||||
|
|
||||||
|
# Local-only listener by default (inside Docker network, it's open to other containers)
|
||||||
|
# To expose to Tailscale, one might add:
|
||||||
|
# listener 1883 <tailscale_ip>
|
||||||
23
hosts/chelsty/runtime/zigbee2mqtt/configuration.yaml
Normal file
23
hosts/chelsty/runtime/zigbee2mqtt/configuration.yaml
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Zigbee2MQTT configuration for CHELSTY
|
||||||
|
homeassistant: true
|
||||||
|
permit_join: false
|
||||||
|
|
||||||
|
mqtt:
|
||||||
|
base_topic: zigbee2mqtt
|
||||||
|
server: mqtt://mosquitto:1883
|
||||||
|
user: ${MQTT_USER}
|
||||||
|
password: ${MQTT_PASSWORD}
|
||||||
|
|
||||||
|
serial:
|
||||||
|
# SLZB-06U network coordinator
|
||||||
|
port: tcp://192.168.1.105:6638
|
||||||
|
adapter: ezsp
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
port: 8080
|
||||||
|
|
||||||
|
advanced:
|
||||||
|
network_key: GENERATE
|
||||||
|
pan_id: GENERATE
|
||||||
|
ext_pan_id: GENERATE
|
||||||
|
channel: 11
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
services:
|
||||||
|
zigbee2mqtt:
|
||||||
|
volumes:
|
||||||
|
- ./configuration.yaml:/app/data/configuration.yaml:ro
|
||||||
|
environment:
|
||||||
|
- MQTT_USER=${MQTT_USER}
|
||||||
|
- MQTT_PASSWORD=${MQTT_PASSWORD}
|
||||||
|
# Healthcheck is already defined in base service, but we ensure compatibility
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:8080"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
89
scripts/bootstrap/chelsty-runtime.sh
Executable file
89
scripts/bootstrap/chelsty-runtime.sh
Executable file
|
|
@ -0,0 +1,89 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# chelsty-runtime.sh - Bootstrap script for CHELSTY edge node runtime
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
|
RUNTIME_DIR="/opt/homelab"
|
||||||
|
CHELSTY_CONFIG="$REPO_ROOT/hosts/chelsty/runtime"
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
log() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||||||
|
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||||
|
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
|
||||||
|
|
||||||
|
log "Starting CHELSTY runtime bootstrap..."
|
||||||
|
|
||||||
|
# 1. Validate Docker availability
|
||||||
|
if ! command -v docker &> /dev/null; then
|
||||||
|
error "Docker is not installed. Please install Docker first."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. Validate compose plugin
|
||||||
|
if ! docker compose version &> /dev/null; then
|
||||||
|
error "Docker Compose plugin is not installed."
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Docker and Compose plugin verified."
|
||||||
|
|
||||||
|
# 3. Create runtime directories
|
||||||
|
log "Creating runtime directories in $RUNTIME_DIR..."
|
||||||
|
sudo mkdir -p "$RUNTIME_DIR/data/mosquitto/config" \
|
||||||
|
"$RUNTIME_DIR/data/mosquitto/data" \
|
||||||
|
"$RUNTIME_DIR/data/mosquitto/log" \
|
||||||
|
"$RUNTIME_DIR/data/zigbee2mqtt/data" \
|
||||||
|
"$RUNTIME_DIR/config/mosquitto" \
|
||||||
|
"$RUNTIME_DIR/config/zigbee2mqtt"
|
||||||
|
|
||||||
|
# 4. Copy runtime templates if absent
|
||||||
|
log "Deploying runtime configurations..."
|
||||||
|
# Mosquitto
|
||||||
|
if [ ! -f "$RUNTIME_DIR/config/mosquitto/mosquitto.conf" ]; then
|
||||||
|
sudo cp "$CHELSTY_CONFIG/mosquitto/mosquitto.conf" "$RUNTIME_DIR/config/mosquitto/"
|
||||||
|
log "Copied mosquitto.conf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$RUNTIME_DIR/config/mosquitto/docker-compose.override.yml" ]; then
|
||||||
|
sudo cp "$CHELSTY_CONFIG/mosquitto/docker-compose.override.yml" "$RUNTIME_DIR/config/mosquitto/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Zigbee2MQTT
|
||||||
|
if [ ! -f "$RUNTIME_DIR/config/zigbee2mqtt/configuration.yaml" ]; then
|
||||||
|
sudo cp "$CHELSTY_CONFIG/zigbee2mqtt/configuration.yaml" "$RUNTIME_DIR/config/zigbee2mqtt/"
|
||||||
|
log "Copied zigbee2mqtt configuration.yaml"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$RUNTIME_DIR/config/zigbee2mqtt/docker-compose.override.yml" ]; then
|
||||||
|
sudo cp "$CHELSTY_CONFIG/zigbee2mqtt/docker-compose.override.yml" "$RUNTIME_DIR/config/zigbee2mqtt/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 5. Create missing .env files from examples
|
||||||
|
log "Checking for environment files..."
|
||||||
|
if [ ! -f "$RUNTIME_DIR/config/zigbee2mqtt/.env" ]; then
|
||||||
|
warn "Creating template .env for Zigbee2MQTT. PLEASE EDIT IT!"
|
||||||
|
echo "MQTT_USER=admin" | sudo tee "$RUNTIME_DIR/config/zigbee2mqtt/.env" > /dev/null
|
||||||
|
echo "MQTT_PASSWORD=password" | sudo tee -a "$RUNTIME_DIR/config/zigbee2mqtt/.env" > /dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 6. Ensure password file exists for Mosquitto
|
||||||
|
if [ ! -f "$RUNTIME_DIR/data/mosquitto/config/password.txt" ]; then
|
||||||
|
log "Creating empty mosquitto password file..."
|
||||||
|
sudo touch "$RUNTIME_DIR/data/mosquitto/config/password.txt"
|
||||||
|
warn "Mosquitto password file is empty. Use 'mosquitto_passwd' to add users."
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Bootstrap complete!"
|
||||||
|
|
||||||
|
echo -e "\n${YELLOW}Next-step instructions:${NC}"
|
||||||
|
echo "1. Edit $RUNTIME_DIR/config/zigbee2mqtt/.env with real credentials."
|
||||||
|
echo "2. Add Mosquitto user: sudo mosquitto_passwd -b $RUNTIME_DIR/data/mosquitto/config/password.txt <user> <password>"
|
||||||
|
echo "3. Deploy services using the homelab deployment framework:"
|
||||||
|
echo " ./scripts/deploy/deploy-node.sh chelsty"
|
||||||
|
echo "4. Verify Zigbee2MQTT logs to ensure it connects to SLZB-06U."
|
||||||
|
echo "5. Check Home Assistant (separate VM) for MQTT discovery."
|
||||||
Loading…
Reference in a new issue