mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 18:45:53 +00:00
62bfdbca7e
Open the v6.4.3 candidate line from main. The v6.4.2 tag was staged on 2026-08-31 but never activated: its release run was cancelled after the private Pro build failed the compiler memory gate, so the latest published stable is still v6.4.1. This candidate carries the complete v6.4.2 change set plus the corrections landed since that tag, including the stale PBS Backup Running state (#1815), the Windows Unified Agent auto-update 404 (#1820), and shared-token same-hostname agent identity collapse (#1753). Packet: VERSION, compose and install-docker defaults, Helm chart metadata, release notes with a declined visual plan, changelog, pointer docs and the shipped docs mirror, and the deployment-installability cutoff note. Rollback target is v6.4.1 and the mobile decision is no-mobile-impact. Tests: the packet tests now describe the 6.4.3 train, v6.4.2 is recorded as an unpublished stable so it is never derived as the previous stable or rollback target, and the Python v6.4.2 notes expectation matches the phrase the notes actually use.
163 lines
4.7 KiB
Bash
Executable File
163 lines
4.7 KiB
Bash
Executable File
#!/bin/bash
|
|
# install-docker.sh - Turnkey Pulse installation for Docker hosts
|
|
# Generates docker-compose.yml and .env
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
|
|
DOCKER_IMAGE_REPO="${DOCKER_IMAGE_REPO:-rcourtman/pulse}"
|
|
CANONICAL_DEFAULT_PULSE_VERSION="6.4.3-rc.1"
|
|
|
|
resolve_default_pulse_version() {
|
|
if [ -n "${PULSE_IMAGE_VERSION:-}" ]; then
|
|
printf '%s' "${PULSE_IMAGE_VERSION}"
|
|
return
|
|
fi
|
|
|
|
for candidate in "${PULSE_VERSION_FILE:-}" "${SCRIPT_DIR}/../VERSION" "${PWD}/VERSION"; do
|
|
if [ -n "${candidate}" ] && [ -f "${candidate}" ]; then
|
|
local version
|
|
version=$(tr -d '\r\n' < "${candidate}" 2>/dev/null || true)
|
|
if [ -n "${version}" ]; then
|
|
printf '%s' "${version}"
|
|
return
|
|
fi
|
|
fi
|
|
done
|
|
|
|
printf '%s' "${CANONICAL_DEFAULT_PULSE_VERSION}"
|
|
}
|
|
|
|
DEFAULT_PULSE_IMAGE="${DOCKER_IMAGE_REPO}:$(resolve_default_pulse_version)"
|
|
PULSE_IMAGE="${PULSE_IMAGE:-${DEFAULT_PULSE_IMAGE}}"
|
|
PULSE_PORT="${PULSE_PORT:-7655}"
|
|
|
|
# ============================================
|
|
# Pre-flight Checks
|
|
# ============================================
|
|
|
|
echo "============================================"
|
|
echo " Pulse Turnkey Docker Installation"
|
|
echo "============================================"
|
|
echo ""
|
|
|
|
# Check if running as root (early check for better error messages)
|
|
if [ "$EUID" -ne 0 ]; then
|
|
echo "❌ ERROR: This script must be run as root"
|
|
echo ""
|
|
echo "Please run: sudo $0"
|
|
exit 1
|
|
fi
|
|
|
|
# Detect if running in a container
|
|
if [ -f /.dockerenv ] || [ -f /run/.containerenv ]; then
|
|
echo "❌ ERROR: This script must run on the Docker host, not inside a container"
|
|
echo ""
|
|
echo "Please run this script on your Docker host machine."
|
|
exit 1
|
|
fi
|
|
|
|
# Check if Docker is installed
|
|
if ! command -v docker &> /dev/null; then
|
|
echo "❌ ERROR: Docker is not installed"
|
|
echo ""
|
|
echo "Please install Docker first:"
|
|
echo " curl -fsSL https://get.docker.com | sh"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if docker compose is available
|
|
if ! docker compose version &> /dev/null; then
|
|
echo "⚠️ Warning: 'docker compose' command not found"
|
|
echo " You may need to use 'docker-compose' instead"
|
|
echo ""
|
|
fi
|
|
|
|
# ============================================
|
|
# Generate Docker Compose Configuration
|
|
# ============================================
|
|
|
|
COMPOSE_FILE="./docker-compose.yml"
|
|
|
|
# Check if docker-compose.yml already exists (idempotency)
|
|
if [ -f "$COMPOSE_FILE" ]; then
|
|
echo "⚠️ docker-compose.yml already exists"
|
|
echo " Backing up to docker-compose.yml.backup"
|
|
cp "$COMPOSE_FILE" "${COMPOSE_FILE}.backup"
|
|
fi
|
|
|
|
cat > "$COMPOSE_FILE" << COMPOSE_EOF
|
|
version: '3.8'
|
|
|
|
services:
|
|
pulse:
|
|
image: \${PULSE_IMAGE:-${DEFAULT_PULSE_IMAGE}}
|
|
container_name: pulse
|
|
restart: unless-stopped
|
|
user: "1000:1000"
|
|
security_opt:
|
|
- apparmor=unconfined
|
|
ports:
|
|
- "\${PULSE_PORT:-7655}:7655"
|
|
volumes:
|
|
- pulse-data:/data
|
|
environment:
|
|
- TZ=\${TZ:-UTC}
|
|
healthcheck:
|
|
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:7655/api/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 10s
|
|
|
|
volumes:
|
|
pulse-data:
|
|
driver: local
|
|
COMPOSE_EOF
|
|
|
|
echo "✓ Generated docker-compose.yml"
|
|
echo ""
|
|
|
|
# Create .env file with defaults
|
|
ENV_FILE=".env"
|
|
if [ -f "$ENV_FILE" ]; then
|
|
echo "⚠️ .env file already exists - not overwriting"
|
|
echo ""
|
|
else
|
|
cat > "$ENV_FILE" << EOF
|
|
PULSE_IMAGE=${PULSE_IMAGE}
|
|
PULSE_PORT=${PULSE_PORT}
|
|
TZ=$(timedatectl show -p Timezone --value 2>/dev/null || echo "UTC")
|
|
EOF
|
|
echo "✓ Generated .env file"
|
|
echo ""
|
|
fi
|
|
|
|
# ============================================
|
|
# Installation Complete
|
|
# ============================================
|
|
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo "✅ Installation Complete!"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
echo "Start Pulse with:"
|
|
echo " docker compose up -d"
|
|
echo ""
|
|
echo "Or with docker run:"
|
|
echo " docker run -d \\"
|
|
echo " --name pulse \\"
|
|
echo " --user 1000:1000 \\"
|
|
echo " --security-opt apparmor=unconfined \\"
|
|
echo " --restart unless-stopped \\"
|
|
echo " -p ${PULSE_PORT}:7655 \\"
|
|
echo " -v pulse-data:/data \\"
|
|
echo " ${PULSE_IMAGE}"
|
|
echo ""
|
|
echo "Access Pulse at: http://$(hostname -I | awk '{print $1}'):${PULSE_PORT}"
|
|
echo ""
|
|
echo "Notes:"
|
|
echo " - For temperature monitoring, use the unified agent on Proxmox hosts."
|
|
echo " - SSH-based temperature collection from containers is not recommended."
|
|
echo ""
|