Files
gitea-migration/setup/pi-monitoring/bootstrap_pi.sh

124 lines
3.2 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# shellcheck source=./lib.sh
source "$SCRIPT_DIR/lib.sh"
TIMEZONE="America/New_York"
SSH_PORT="22"
AUTO_YES=false
ENABLE_UFW=true
usage() {
cat <<USAGE
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)
--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
USAGE
}
for arg in "$@"; do
case "$arg" in
--timezone=*) TIMEZONE="${arg#*=}" ;;
--ssh-port=*) SSH_PORT="${arg#*=}" ;;
--skip-firewall) ENABLE_UFW=false ;;
--yes|-y) AUTO_YES=true ;;
--help|-h) usage; exit 0 ;;
*) log_error "Unknown argument: $arg"; usage; exit 1 ;;
esac
done
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
log_info "Cancelled"
exit 0
fi
arch="$(uname -m)"
if [[ "$arch" != "aarch64" && "$arch" != "arm64" ]]; then
log_warn "Detected architecture '$arch' (expected ARM64 for Raspberry Pi 4)."
fi
log_info "Updating OS packages..."
sudo apt update
sudo apt full-upgrade -y
log_info "Installing base packages..."
sudo apt install -y \
ca-certificates \
curl \
fail2ban \
git \
htop \
jq \
ufw \
unattended-upgrades
log_info "Setting timezone to $TIMEZONE..."
sudo timedatectl set-timezone "$TIMEZONE"
log_info "Enabling security services..."
sudo systemctl enable --now fail2ban
sudo systemctl enable --now unattended-upgrades || true
if ! command -v docker >/dev/null 2>&1; then
log_info "Installing Docker Engine..."
curl -fsSL https://get.docker.com | sh
else
log_success "Docker already installed"
fi
log_info "Enabling Docker service..."
sudo systemctl enable --now docker
log_info "Configuring Docker daemon defaults..."
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json >/dev/null <<'JSON'
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"live-restore": true
}
JSON
sudo systemctl restart docker
if id -nG "$USER" | grep -qw docker; then
log_success "User '$USER' is already in docker group"
else
log_info "Adding '$USER' to docker group..."
sudo usermod -aG docker "$USER"
log_warn "Log out and back in once for docker group membership to apply."
fi
if [[ "$ENABLE_UFW" == "true" ]]; then
log_info "Configuring UFW firewall rules..."
sudo ufw allow "${SSH_PORT}/tcp"
sudo ufw allow 9443/tcp # Portainer HTTPS
sudo ufw allow 8000/tcp # Portainer Edge
sudo ufw allow 3000/tcp # Grafana
sudo ufw allow 3001/tcp # Uptime Kuma
sudo ufw allow 9090/tcp # Prometheus
sudo ufw --force enable
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 "3) Copy stack.env.example to stack.env and run deploy_stack.sh"