#!/usr/bin/env bash # Установка и обновление Сплит-тренера на Debian 12/13: nginx + статические файлы. # # sudo ./deploy/install-debian.sh # за обратным прокси: слушаем 127.0.0.1:8080 # sudo LISTEN=80 DOMAIN=trainer.example.com ./deploy/install-debian.sh # без прокси, напрямую на порту 80 # # Повторный запуск обновляет файлы сайта и конфиг. Ничего, кроме этого сайта, скрипт не трогает. set -euo pipefail LISTEN="${LISTEN:-127.0.0.1:8080}" # адрес:порт или просто порт DOMAIN="${DOMAIN:-_}" # server_name; "_" = любое имя WEBROOT="${WEBROOT:-/var/www/split-trainer}" API_UPSTREAM="${API_UPSTREAM:-http://127.0.0.1:8000}" # где слушает API аккаунтов (ставится deploy/install-api-debian.sh) NAME="split-trainer" die() { echo "Ошибка: $*" >&2; exit 1; } [ "$(id -u)" -eq 0 ] || die "запустите от root: sudo $0" HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SRC="$HERE/../public" CONF_TEMPLATE="$HERE/$NAME.conf" [ -f "$SRC/index.html" ] || die "не найден $SRC/index.html: запускайте скрипт из клонированного репозитория" [ -f "$CONF_TEMPLATE" ] || die "не найден $CONF_TEMPLATE" # Значения подставляются в sed: не пускаем туда ничего, кроме безопасных символов [[ "$LISTEN" =~ ^[][0-9A-Za-z.:_-]+$ ]] || die "некорректный LISTEN: $LISTEN" [[ "$DOMAIN" =~ ^[0-9A-Za-z._*-]+( [0-9A-Za-z._*-]+)*$ ]] || die "некорректный DOMAIN: $DOMAIN" [[ "$WEBROOT" =~ ^/[0-9A-Za-z._/-]+$ ]] || die "некорректный WEBROOT: $WEBROOT" [[ "$API_UPSTREAM" =~ ^http://(127\.0\.0\.1|\[::1\]):[0-9]{1,5}$ ]] || die "некорректный API_UPSTREAM (нужен http://127.0.0.1:порт или http://[::1]:порт, без имён: DNS здесь не работает): $API_UPSTREAM" # Скрипт стирает старые файлы в WEBROOT: системные каталоги и каталоги верхнего уровня запрещаем case "$WEBROOT" in /|/etc|/etc/*|/usr|/usr/*|/bin|/bin/*|/sbin|/sbin/*|/lib*|/boot|/boot/*|/root|/root/*|/proc|/proc/*|/sys|/sys/*|/dev|/dev/*|/home|/var|/opt|/srv|/run|/run/*|/tmp) die "WEBROOT не может быть системным каталогом: $WEBROOT (подойдёт, например, /var/www/split-trainer)";; esac . /etc/os-release if [ "${ID:-}" != "debian" ] || { [ "${VERSION_ID:-}" != "12" ] && [ "${VERSION_ID:-}" != "13" ]; }; then [ "${FORCE:-0}" = "1" ] || die "скрипт рассчитан на Debian 12/13 (у вас: ${PRETTY_NAME:-неизвестно}). Чтобы всё равно продолжить: FORCE=1" fi echo "==> Устанавливаю nginx" export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y -qq --no-install-recommends nginx >/dev/null echo "==> Копирую сайт в $WEBROOT" install -d -m 755 "$WEBROOT" find "$WEBROOT" -mindepth 1 -maxdepth 1 -type f -delete # убираем только файлы прошлой версии install -m 644 "$SRC"/* "$WEBROOT"/ echo "==> Настраиваю nginx (listen $LISTEN, server_name $DOMAIN)" CONF="/etc/nginx/sites-available/$NAME.conf" sed -e "s|^\(\s*\)listen 8080;.*|\1listen $LISTEN;|" \ -e "s|^\(\s*\)server_name _;.*|\1server_name $DOMAIN;|" \ -e "s|^\(\s*\)root /usr/share/nginx/html;.*|\1root $WEBROOT;|" \ -e "s|^\(\s*\)set \$api_upstream .*|\1set \$api_upstream $API_UPSTREAM;|" \ -e '/^\s*resolver 127\.0\.0\.11/d' \ "$CONF_TEMPLATE" > "$CONF" # DNS Docker на хосте не нужен: API по адресу 127.0.0.1 ln -sf "$CONF" "/etc/nginx/sites-enabled/$NAME.conf" nginx -t systemctl enable --now nginx >/dev/null 2>&1 systemctl reload nginx # Проверяем, что сайт действительно отвечает HOSTPORT="$LISTEN"; [[ "$HOSTPORT" =~ ^[0-9]+$ ]] && HOSTPORT="127.0.0.1:$HOSTPORT" [ "${HOSTPORT%%:*}" = "0.0.0.0" ] && HOSTPORT="127.0.0.1:${HOSTPORT##*:}" if command -v curl >/dev/null 2>&1 && ! curl -fsS -m 5 -o /dev/null "http://$HOSTPORT/healthz" -H "Host: ${DOMAIN%% *}"; then echo "Предупреждение: проверка http://$HOSTPORT/healthz не прошла. Если порт 80 занят сайтом по умолчанию, см. docs/DEPLOY.md" >&2 fi echo "==> Готово: http://$HOSTPORT/"