feat: add runner conversion scripts and strengthen cutover automation
This commit is contained in:
@@ -51,6 +51,25 @@ ai.sintheus.com {
|
||||
}
|
||||
}
|
||||
|
||||
getter.sintheus.com {
|
||||
import common_security
|
||||
|
||||
reverse_proxy http://192.168.1.3:8181 {
|
||||
import proxy_headers
|
||||
}
|
||||
}
|
||||
|
||||
portainer.sintheus.com {
|
||||
import common_security
|
||||
|
||||
reverse_proxy https://192.168.1.181:9443 {
|
||||
import proxy_headers
|
||||
transport http {
|
||||
tls_insecure_skip_verify
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
photos.sintheus.com {
|
||||
import common_security
|
||||
|
||||
|
||||
49
setup/nginx-to-caddy/toggle_dns.sh
Executable file
49
setup/nginx-to-caddy/toggle_dns.sh
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Toggle DNS between Pi-hole and Cloudflare on all active network services.
|
||||
# Usage: ./toggle_dns.sh
|
||||
# Requires sudo for networksetup.
|
||||
|
||||
PIHOLE="192.168.1.4"
|
||||
CLOUDFLARE="1.1.1.1"
|
||||
|
||||
# Get all hardware network services (Wi-Fi, Ethernet, Thunderbolt, USB, etc.)
|
||||
services=()
|
||||
while IFS= read -r line; do
|
||||
[[ "$line" == *"*"* ]] && continue # skip disabled services
|
||||
services+=("$line")
|
||||
done < <(networksetup -listallnetworkservices 2>/dev/null | tail -n +2)
|
||||
|
||||
if [[ ${#services[@]} -eq 0 ]]; then
|
||||
echo "No network services found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Detect current mode from the first service that has a DNS set
|
||||
current_dns=""
|
||||
for svc in "${services[@]}"; do
|
||||
dns=$(networksetup -getdnsservers "$svc" 2>/dev/null | head -1)
|
||||
if [[ "$dns" != *"aren't any"* ]] && [[ -n "$dns" ]]; then
|
||||
current_dns="$dns"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$current_dns" == "$CLOUDFLARE" ]]; then
|
||||
target="$PIHOLE"
|
||||
label="Pi-hole"
|
||||
else
|
||||
target="$CLOUDFLARE"
|
||||
label="Cloudflare"
|
||||
fi
|
||||
|
||||
echo "Switching all services to ${label} (${target})..."
|
||||
for svc in "${services[@]}"; do
|
||||
sudo networksetup -setdnsservers "$svc" "$target"
|
||||
echo " ${svc} → ${target}"
|
||||
done
|
||||
|
||||
sudo dscacheutil -flushcache
|
||||
sudo killall -HUP mDNSResponder 2>/dev/null || true
|
||||
echo "DNS set to ${label} (${target})"
|
||||
@@ -5,7 +5,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
# shellcheck source=./lib.sh
|
||||
source "$SCRIPT_DIR/lib.sh"
|
||||
|
||||
TIMEZONE="America/New_York"
|
||||
TIMEZONE="America/Chicago"
|
||||
SSH_PORT="22"
|
||||
AUTO_YES=false
|
||||
ENABLE_UFW=true
|
||||
@@ -17,14 +17,14 @@ Usage: $(basename "$0") [options]
|
||||
Prepare a brand-new Raspberry Pi OS host for monitoring stack workloads.
|
||||
|
||||
Options:
|
||||
--timezone=ZONE Set system timezone (default: America/New_York)
|
||||
--timezone=ZONE Set system timezone (default: America/Chicago)
|
||||
--ssh-port=PORT SSH port allowed by firewall (default: 22)
|
||||
--skip-firewall Skip UFW configuration
|
||||
--yes, -y Non-interactive; skip confirmation prompts
|
||||
--help, -h Show help
|
||||
|
||||
Example:
|
||||
$(basename "$0") --timezone=America/New_York --yes
|
||||
$(basename "$0") --timezone=America/Chicago --yes
|
||||
USAGE
|
||||
}
|
||||
|
||||
@@ -39,6 +39,19 @@ for arg in "$@"; do
|
||||
esac
|
||||
done
|
||||
|
||||
# Validate --ssh-port (must be 1-65535) before we risk enabling UFW with a bad rule
|
||||
if ! [[ "$SSH_PORT" =~ ^[0-9]+$ ]] || [[ "$SSH_PORT" -lt 1 ]] || [[ "$SSH_PORT" -gt 65535 ]]; then
|
||||
log_error "--ssh-port must be a number between 1 and 65535 (got: '$SSH_PORT')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate --timezone against timedatectl's known list
|
||||
if ! timedatectl list-timezones 2>/dev/null | grep -qx "$TIMEZONE"; then
|
||||
log_error "Unknown timezone: '$TIMEZONE'"
|
||||
log_error "Run 'timedatectl list-timezones' for valid options"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
require_cmd sudo apt systemctl timedatectl curl
|
||||
|
||||
if ! confirm_action "This will install/update OS packages and Docker on this Pi. Continue?" "$AUTO_YES"; then
|
||||
@@ -85,6 +98,10 @@ sudo systemctl enable --now docker
|
||||
|
||||
log_info "Configuring Docker daemon defaults..."
|
||||
sudo mkdir -p /etc/docker
|
||||
if [[ -f /etc/docker/daemon.json ]]; then
|
||||
sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.bak
|
||||
log_info "Backed up existing daemon.json to daemon.json.bak"
|
||||
fi
|
||||
sudo tee /etc/docker/daemon.json >/dev/null <<'JSON'
|
||||
{
|
||||
"log-driver": "json-file",
|
||||
@@ -119,5 +136,5 @@ fi
|
||||
log_success "Bootstrap complete"
|
||||
log_info "Recommended next steps:"
|
||||
log_info "1) Re-login to apply docker group membership"
|
||||
log_info "2) Run setup/pi-monitoring/mount_ssd.sh"
|
||||
log_info "2) (Optional) Run setup/pi-monitoring/mount_ssd.sh if you have an SSD"
|
||||
log_info "3) Copy stack.env.example to stack.env and run deploy_stack.sh"
|
||||
|
||||
@@ -40,7 +40,9 @@ services:
|
||||
command:
|
||||
- '--config.file=/etc/prometheus/prometheus.yml'
|
||||
- '--storage.tsdb.path=/prometheus'
|
||||
- '--storage.tsdb.retention.time=30d'
|
||||
- '--storage.tsdb.retention.time=${PROMETHEUS_RETENTION_TIME:-15d}'
|
||||
- '--storage.tsdb.retention.size=${PROMETHEUS_RETENTION_SIZE:-2GB}'
|
||||
- '--storage.tsdb.wal-compression'
|
||||
- '--web.enable-lifecycle'
|
||||
ports:
|
||||
- "${BIND_IP:-0.0.0.0}:${PROMETHEUS_PORT:-9090}:9090"
|
||||
|
||||
11
setup/pi-monitoring/portainer-agent.sh
Normal file
11
setup/pi-monitoring/portainer-agent.sh
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
docker run -d \
|
||||
-p 9001:9001 \
|
||||
--name portainer_agent \
|
||||
--restart=always \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v /var/lib/docker/volumes:/var/lib/docker/volumes \
|
||||
-v /:/host \
|
||||
portainer/agent:2.39.0
|
||||
@@ -10,7 +10,7 @@ COMPOSE_PROJECT_NAME=pi-monitoring
|
||||
OPS_ROOT=/srv/ops
|
||||
|
||||
# Host timezone for containers
|
||||
TZ=America/New_York
|
||||
TZ=America/Chicago
|
||||
|
||||
# Bind IP for published ports (0.0.0.0 = all interfaces)
|
||||
BIND_IP=0.0.0.0
|
||||
@@ -34,6 +34,11 @@ UPTIME_KUMA_IMAGE=louislam/uptime-kuma:1
|
||||
GRAFANA_ADMIN_USER=admin
|
||||
GRAFANA_ADMIN_PASSWORD=replace-with-strong-password
|
||||
|
||||
# Prometheus retention (whichever limit is hit first wins)
|
||||
# Reduce these on microSD to prevent filling the card.
|
||||
PROMETHEUS_RETENTION_TIME=15d
|
||||
PROMETHEUS_RETENTION_SIZE=2GB
|
||||
|
||||
# Optional comma-separated plugin list for Grafana
|
||||
# Example: grafana-piechart-panel,grafana-clock-panel
|
||||
GRAFANA_PLUGINS=
|
||||
|
||||
Reference in New Issue
Block a user