Исправлен деплой скрипт

This commit is contained in:
2026-10-07 16:20:42 +03:00
parent d897601d88
commit cc194b8eee
7 changed files with 201 additions and 19 deletions

120
deploy/nginx-site.sh Executable file
View File

@@ -0,0 +1,120 @@
#!/usr/bin/env bash
# Генерирует и включает конфиг nginx для сайта расписания.
#
# SSL обеспечивает сертификат родительского домена (обычно wildcard *.example.ru):
# отдельный certbot для поддомена не нужен — достаточно имени сертификата.
# Список имён: sudo ls /etc/letsencrypt/live/
#
# Имя сертификата берётся из --cert, иначе — родительский домен от --domain
# (schedule.example.ru -> example.ru). Порт фронта берётся из --port, иначе из
# FRONTEND_PORT файла .env в корне проекта, иначе 8090.
#
# Примеры:
# deploy/nginx-site.sh --print # показать конфиг, ничего не менять
# sudo deploy/nginx-site.sh # поставить и перечитать nginx
# sudo deploy/nginx-site.sh --domain sched.example.ru --cert example.ru
set -euo pipefail
usage() {
grep '^#' "$0" | sed 's/^# \{0,1\}//' | tail -n +2
}
DOMAIN="schedule.our-place.ru"
CERT_NAME=""
FRONTEND_PORT=""
PRINT=0
while [[ $# -gt 0 ]]; do
case "$1" in
--domain) DOMAIN="$2"; shift 2 ;;
--cert) CERT_NAME="$2"; shift 2 ;;
--port) FRONTEND_PORT="$2"; shift 2 ;;
--print) PRINT=1; shift ;;
-h|--help) usage; exit 0 ;;
*) echo "Неизвестный аргумент: $1 (см. --help)" >&2; exit 2 ;;
esac
done
[[ $DOMAIN =~ ^[a-zA-Z0-9.-]+$ ]] || { echo "Кривое имя домена: $DOMAIN" >&2; exit 2; }
if [[ -z $CERT_NAME ]]; then
CERT_NAME="${DOMAIN#*.}" # schedule.our-place.ru -> our-place.ru (wildcard родителя)
fi
[[ $CERT_NAME =~ ^[a-zA-Z0-9.-]+$ ]] || { echo "Кривое имя сертификата: $CERT_NAME" >&2; exit 2; }
if [[ -z $FRONTEND_PORT ]]; then
# FRONTEND_PORT из .env; значение вида «127.0.0.1:8090» трактуем как «порт после двоеточия»
FRONTEND_PORT=$(
grep -E '^FRONTEND_PORT=' .env 2>/dev/null | tail -1 | cut -d= -f2- \
| tr -d ' "' | awk -F: '{print $NF}'
) || FRONTEND_PORT=""
fi
FRONTEND_PORT=${FRONTEND_PORT:-8090}
[[ $FRONTEND_PORT =~ ^[0-9]+$ ]] || { echo "Не разобрал FRONTEND_PORT из .env, задайте --port" >&2; exit 2; }
read -r -d '' CONFIG <<'TEMPLATE' || true
# Сгенерировано deploy/nginx-site.sh — правки вносить в скрипт, не сюда.
server {
listen 80;
listen [::]:80;
server_name __DOMAIN__;
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name __DOMAIN__;
# сертификат родительского домена (обычно wildcard), обновляет certbot родителя
ssl_certificate /etc/letsencrypt/live/__CERT__/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/__CERT__/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
client_max_body_size 8m;
location / {
# порт FRONTEND_PORT из .env стенда
proxy_pass http://127.0.0.1:__PORT__;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
# холодный кэш: бэкенд качает таблицу, до ~2 минут
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}
TEMPLATE
CONFIG=${CONFIG//__DOMAIN__/$DOMAIN}
CONFIG=${CONFIG//__CERT__/$CERT_NAME}
CONFIG=${CONFIG//__PORT__/$FRONTEND_PORT}
if [[ $PRINT == 1 ]]; then
printf '%s\n' "$CONFIG"
exit 0
fi
if [[ $EUID -ne 0 ]]; then
echo "Установка требует root: sudo deploy/nginx-site.sh (посмотреть конфиг — deploy/nginx-site.sh --print)" >&2
exit 1
fi
DEST="/etc/nginx/sites-available/${DOMAIN}"
printf '%s\n' "$CONFIG" > "$DEST"
ln -sf "$DEST" "/etc/nginx/sites-enabled/${DOMAIN}"
if nginx -t 2>&1; then
systemctl reload nginx
echo "Готово: https://${DOMAIN} -> 127.0.0.1:${FRONTEND_PORT} (сертификат ${CERT_NAME})"
else
echo "nginx -t не прошёл: конфиг записан в ${DEST} и включён, но nginx НЕ перечитан. Разберитесь и выполните: sudo nginx -t && sudo systemctl reload nginx" >&2
exit 1
fi