server-monitoring/bootstrap.sh
ShiZa039 45376bfa8d Исполняемые биты для deploy.sh, bootstrap.sh, entrypoint.sh
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 12:54:53 +02:00

141 lines
7 KiB
Bash
Executable file
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# Установка «с нуля» одной командой: ставит зависимости (git, curl, docker,
# compose, htpasswd), клонирует/обновляет репозиторий, создаёт .env (интерактивно
# при первом запуске) и запускает deploy.sh. Идемпотентен — повторный запуск
# просто подтянет свежий код и переприменит конфигурацию.
#
# Использование (на чистом сервере, от root):
# curl -fsSL https://git.sab-core.ru/ShiZa/server-monitoring/raw/branch/main/bootstrap.sh \
# | sudo bash -s -- --repo https://git.sab-core.ru/ShiZa/server-monitoring.git
#
# Или из уже склонированного репозитория:
# sudo bash bootstrap.sh
#
# Флаги: --repo <url> URL git-репозитория (обязателен вне клона)
# --dir <path> куда клонировать (по умолчанию /opt/monitoring)
# --branch <br> ветка (по умолчанию ветка по умолчанию репо)
set -euo pipefail
C_RED=$'\033[31m'; C_GREEN=$'\033[32m'; C_YELLOW=$'\033[33m'; C_RESET=$'\033[0m'
say() { echo "${C_GREEN}==>${C_RESET} $*"; }
warn() { echo "${C_YELLOW}[WARN]${C_RESET} $*"; }
die() { echo "${C_RED}[ERR]${C_RESET} $*" >&2; exit 1; }
REPO_URL=""
TARGET_DIR="/opt/monitoring"
BRANCH=""
while [ $# -gt 0 ]; do
case "$1" in
--repo) REPO_URL="${2:?}"; shift 2 ;;
--dir) TARGET_DIR="${2:?}"; shift 2 ;;
--branch) BRANCH="${2:?}"; shift 2 ;;
-h|--help) grep '^#' "$0" | head -20; exit 0 ;;
*) die "неизвестный аргумент: $1" ;;
esac
done
[ "$(id -u)" = 0 ] || die "нужны права root: запусти через sudo"
command -v apt-get >/dev/null 2>&1 || die "поддерживается только Debian/Ubuntu (нужен apt-get)"
# --- 1. Базовые пакеты -------------------------------------------------------
declare -A CMD_PKG=([curl]=curl [git]=git [htpasswd]=apache2-utils)
MISSING=()
for cmd in "${!CMD_PKG[@]}"; do
command -v "$cmd" >/dev/null 2>&1 || MISSING+=("${CMD_PKG[$cmd]}")
done
if [ "${#MISSING[@]}" -gt 0 ]; then
say "Ставлю пакеты: ${MISSING[*]}"
apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq ca-certificates "${MISSING[@]}"
fi
# --- 2. Docker + compose -----------------------------------------------------
if ! command -v docker >/dev/null 2>&1; then
say "Docker не найден — ставлю через get.docker.com"
curl -fsSL https://get.docker.com | sh
fi
if ! docker compose version >/dev/null 2>&1; then
say "Плагин docker compose не найден — ставлю docker-compose-plugin"
apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq docker-compose-plugin \
|| die "не удалось поставить docker-compose-plugin — поставь вручную"
fi
systemctl enable --now docker >/dev/null 2>&1 || true
docker info >/dev/null 2>&1 || die "docker-демон не запущен (systemctl status docker)"
# --- 3. Репозиторий ----------------------------------------------------------
if [ -z "${REPO_URL}" ] && [ -f ./deploy.sh ] && [ -f ./docker-compose.yml ]; then
# запущен из уже склонированного репозитория
TARGET_DIR="$(pwd)"
say "Использую текущий клон: ${TARGET_DIR}"
if [ -d .git ] && git remote get-url origin >/dev/null 2>&1; then
git pull --ff-only || warn "git pull не удался (локальные изменения?) — продолжаю с текущим кодом"
fi
elif [ -d "${TARGET_DIR}/.git" ]; then
say "Обновляю ${TARGET_DIR}"
git -C "${TARGET_DIR}" fetch --all --prune
if [ -n "${BRANCH}" ]; then git -C "${TARGET_DIR}" checkout "${BRANCH}"; fi
git -C "${TARGET_DIR}" pull --ff-only || warn "git pull не удался — продолжаю с текущим кодом"
else
[ -n "${REPO_URL}" ] || die "укажи --repo <url> (или запусти скрипт из клона репозитория)"
say "Клонирую ${REPO_URL}${TARGET_DIR}"
if [ -n "${BRANCH}" ]; then
git clone --branch "${BRANCH}" "${REPO_URL}" "${TARGET_DIR}"
else
git clone "${REPO_URL}" "${TARGET_DIR}"
fi
fi
cd "${TARGET_DIR}"
# стек может лежать в подкаталоге monitoring/ репозитория
[ -f deploy.sh ] || { [ -f monitoring/deploy.sh ] && cd monitoring; } || die "deploy.sh не найден в репозитории"
# --- 4. .env: интерактивное создание при первом запуске ----------------------
if [ ! -f .env ]; then
cp .env.example .env
chmod 600 .env
if [ -r /dev/tty ] && [ -w /dev/tty ]; then
say "Первый запуск — настрою .env (значения можно потом поменять: nano .env && bash deploy.sh)"
DEFAULT_IP=""
if command -v tailscale >/dev/null 2>&1; then
DEFAULT_IP="$(tailscale ip -4 2>/dev/null | head -1 || true)"
fi
[ -n "${DEFAULT_IP}" ] || DEFAULT_IP="$(hostname -I 2>/dev/null | awk '{print $1}')"
echo "Адреса на интерфейсах:" >/dev/tty
ip -o -4 addr show scope global 2>/dev/null | awk '{print " " $2 ": " $4}' >/dev/tty || true
read -r -p "BIND_IP (tailnet или публичный IP) [${DEFAULT_IP}]: " BIND_IP </dev/tty
BIND_IP="${BIND_IP:-${DEFAULT_IP}}"
[ -n "${BIND_IP}" ] || die "BIND_IP обязателен"
DEFAULT_NAME="$(hostname -s)"
read -r -p "SERVER_NAME [${DEFAULT_NAME}]: " SERVER_NAME </dev/tty
SERVER_NAME="${SERVER_NAME:-${DEFAULT_NAME}}"
GRAFANA_ADMIN_PASSWORD=""
while [ -z "${GRAFANA_ADMIN_PASSWORD}" ]; do
read -r -s -p "Пароль admin для Grafana: " GRAFANA_ADMIN_PASSWORD </dev/tty; echo >/dev/tty
done
read -r -s -p "METRICS_PASSWORD (basic auth на Prometheus/Alertmanager/node_exporter; ПУСТО допустимо только для tailnet-серверов): " METRICS_PASSWORD </dev/tty
echo >/dev/tty
[ -n "${METRICS_PASSWORD}" ] || warn "METRICS_PASSWORD пуст — метрики будут без аутентификации"
sed -i \
-e "s|^BIND_IP=.*|BIND_IP=${BIND_IP}|" \
-e "s|^SERVER_NAME=.*|SERVER_NAME=${SERVER_NAME}|" \
-e "s|^GRAFANA_ADMIN_PASSWORD=.*|GRAFANA_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}|" \
-e "s|^METRICS_PASSWORD=.*|METRICS_PASSWORD=${METRICS_PASSWORD}|" \
.env
say ".env создан. Списки CRITICAL_CONTAINERS / CRITICAL_UNITS и Telegram-токены — правь в $(pwd)/.env"
else
warn "Нет терминала для вопросов: создан $(pwd)/.env из шаблона."
warn "Заполни его (nano .env) и запусти: bash deploy.sh"
exit 0
fi
fi
# --- 5. Деплой ---------------------------------------------------------------
say "Запускаю deploy.sh"
bash deploy.sh