/
AlexGromer
/
local-stack-test-work
Обзор
Документация
Войти
/
AlexGromer
/
local-stack-test-work
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
setup.sh
121 строка
6 KB
AlexGromer
Initial commit
24 июн 2026, 12:53
24 июн 2026, 12:53
025dfc6
Код
Авторство
О чём код?
#!/usr/bin/env bash # ===================================================================== # setup.sh — ОДИН линейный интерактивный скрипт. # Запускать ПЕРЕД `docker compose up`. # Что делает (сверху вниз): # 1) спрашивает параметры (Enter = значение по умолчанию в скобках) # 2) пишет .env # 3) рендерит nginx/nginx.conf из nginx/nginx.conf.template # 4) генерит self-signed сертификат (openssl) с нужным SAN # Повторный запуск подставляет текущие значения из .env как умолчания. # ===================================================================== set -euo pipefail cd "$(dirname "${BASH_SOURCE[0]}")" echo "============================================================" echo " Настройка локального стенда (nginx + backend + PG + Redis)" echo "============================================================" # --- подхватываем существующий .env для умолчаний (если уже настраивали) --- if [[ -f .env ]]; then echo " (найден .env — его значения подставлены как умолчания)" set -a; . ./.env; set +a fi # helper: спросить с дефолтом. Работает и интерактивно, и при piped stdin. ask() { local prompt="$1" def="${2:-}" ans read -rp " ${prompt} [${def}]: " ans || ans="" printf '%s' "${ans:-$def}" } # helper: пароль. Введён -> берём; иначе оставляем старый; иначе генерим hex. ask_secret() { local prompt="$1" current="${2:-}" ans read -rp " ${prompt} [Enter = сгенерировать]: " ans || ans="" if [[ -n "$ans" ]]; then printf '%s' "$ans" elif [[ -n "$current" ]]; then printf '%s' "$current" else openssl rand -hex 16; fi } echo echo " -- TLS / сеть --" SERVER_NAME="$(ask 'Доменное имя (server_name + CN сертификата)' "${SERVER_NAME:-localhost}")" echo " Доп. SAN: IP/домены для доступа извне, ЧЕРЕЗ ПРОБЕЛ." echo " Пример для LAN: 192.168.1.50 app.example.test" CERT_EXTRA_SANS="$(ask 'Доп. SAN (IP/домены)' "${CERT_EXTRA_SANS:-127.0.0.1}")" echo echo " -- backend / лимиты --" BACKEND_PORT="$(ask 'Порт backend' "${BACKEND_PORT:-8080}")" RATE_LIMIT_RPS="$(ask 'Rate limit, запросов/сек на IP' "${RATE_LIMIT_RPS:-10}")" RATE_LIMIT_BURST="$(ask 'Rate limit burst' "${RATE_LIMIT_BURST:-20}")" BODY_LIMIT="$(ask 'Лимит тела запроса (напр. 10m)' "${BODY_LIMIT:-10m}")" echo echo " -- секреты (пароли без пробелов и спецсимволов shell) --" POSTGRES_USER="$(ask 'Postgres: логин' "${POSTGRES_USER:-appuser}")" POSTGRES_DB="$(ask 'Postgres: имя БД' "${POSTGRES_DB:-appdb}")" POSTGRES_PASSWORD="$(ask_secret 'Postgres: пароль' "${POSTGRES_PASSWORD:-}")" REDIS_PASSWORD="$(ask_secret 'Redis: пароль' "${REDIS_PASSWORD:-}")" BACKEND_HOST="backend" # имя docker-сервиса, не меняется CERT_DAYS="${CERT_DAYS:-365}" echo echo "------------------------------------------------------------" echo " Будет применено:" echo " server_name / CN : ${SERVER_NAME}" echo " доп. SAN : ${CERT_EXTRA_SANS} (+ localhost/127.0.0.1)" echo " backend : ${BACKEND_HOST}:${BACKEND_PORT}" echo " rate limit : ${RATE_LIMIT_RPS} r/s (burst ${RATE_LIMIT_BURST})" echo " body limit : ${BODY_LIMIT}" echo " postgres : ${POSTGRES_USER} / ${POSTGRES_DB}" echo " пароли : сохранены в .env" echo "------------------------------------------------------------" # === 1. .env ========================================================= # Значения, которые могут содержать пробелы (SERVER_NAME, CERT_EXTRA_SANS), # заключаем в кавычки — чтобы корректно читались при повторном source. { echo "# Сгенерировано setup.sh: $(date -Iseconds)" echo "POSTGRES_USER=${POSTGRES_USER}" echo "POSTGRES_PASSWORD=${POSTGRES_PASSWORD}" echo "POSTGRES_DB=${POSTGRES_DB}" echo "REDIS_PASSWORD=${REDIS_PASSWORD}" echo "BACKEND_HOST=${BACKEND_HOST}" echo "BACKEND_PORT=${BACKEND_PORT}" echo "SERVER_NAME=\"${SERVER_NAME}\"" echo "CERT_EXTRA_SANS=\"${CERT_EXTRA_SANS}\"" echo "CERT_DAYS=${CERT_DAYS}" echo "RATE_LIMIT_RPS=${RATE_LIMIT_RPS}" echo "RATE_LIMIT_BURST=${RATE_LIMIT_BURST}" echo "BODY_LIMIT=${BODY_LIMIT}" } > .env chmod 600 .env echo " [1/3] записан .env" # === 2. nginx.conf из шаблона ======================================== sed \ -e "s|@@SERVER_NAME@@|${SERVER_NAME}|g" \ -e "s|@@BACKEND_HOST@@|${BACKEND_HOST}|g" \ -e "s|@@BACKEND_PORT@@|${BACKEND_PORT}|g" \ -e "s|@@RATE_LIMIT_RPS@@|${RATE_LIMIT_RPS}|g" \ -e "s|@@RATE_LIMIT_BURST@@|${RATE_LIMIT_BURST}|g" \ -e "s|@@BODY_LIMIT@@|${BODY_LIMIT}|g" \ nginx/nginx.conf.template > nginx/nginx.conf echo " [2/3] сгенерирован nginx/nginx.conf" # === 3. self-signed сертификат (отдельный скрипт gen-certs.sh) ======= # gen-certs.sh читает SERVER_NAME/CERT_EXTRA_SANS/CERT_DAYS из только что # записанного .env и собирает SAN. Вызываем через bash (не зависим от +x). bash gen-certs.sh echo " [3/3] сертификат готов (gen-certs.sh)" echo echo "============================================================" echo " Готово. Запускайте стенд:" echo " docker compose up -d" echo " docker compose ps # дождитесь healthy" echo " curl -k https://${SERVER_NAME}/headers" echo "============================================================"