From c374fff4ca5fdb5e0f8a25a97dc3b356bfa4604ffb9c6959bcd11149819f2b2e Mon Sep 17 00:00:00 2001 From: admin Date: Mon, 31 Aug 2026 12:52:14 +0000 Subject: [PATCH] =?UTF-8?q?=D0=97=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D1=84=D0=B0=D0=B9=D0=BB=D1=8B=20=D0=B2=20=C2=AB?= =?UTF-8?q?scripts=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/generate_secrets.sh | 9 ++++ scripts/install.sh | 103 ++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 scripts/generate_secrets.sh create mode 100644 scripts/install.sh diff --git a/scripts/generate_secrets.sh b/scripts/generate_secrets.sh new file mode 100644 index 0000000..0f1e5e9 --- /dev/null +++ b/scripts/generate_secrets.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +# Печатает готовые строки для DJANGO_SECRET_KEY и RESOURCE_TOKEN_SECRET. +# Использование: bash scripts/generate_secrets.sh +set -euo pipefail +python3 - <<'PY' +import secrets +print(f"DJANGO_SECRET_KEY={secrets.token_urlsafe(50)}") +print(f"RESOURCE_TOKEN_SECRET={secrets.token_urlsafe(50)}") +PY diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100644 index 0000000..530f815 --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash +# +# Установка портала администрирования на чистую ВМ (Ubuntu 22.04/24.04 или Debian 12). +# Запускать от root: sudo bash scripts/install.sh +# +# Скрипт идемпотентен настолько, насколько это возможно для apt/systemd, +# но НЕ подставляет секреты за вас — .env нужно подготовить заранее +# (см. README.md, шаг 5) и положить путь к нему в переменную ENV_FILE ниже +# либо передать первым аргументом. + +set -euo pipefail + +APP_USER="adminportal" +APP_DIR="/opt/admin-portal" +ENV_DIR="/etc/admin-portal" +ENV_FILE="${1:-$(pwd)/.env}" +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +if [[ $EUID -ne 0 ]]; then + echo "Запускать от root: sudo bash scripts/install.sh [путь_к_.env]" >&2 + exit 1 +fi + +if [[ ! -f "$ENV_FILE" ]]; then + echo "Не найден .env файл: $ENV_FILE" >&2 + echo "Скопируйте .env.example -> .env, заполните значения и повторите запуск." >&2 + exit 1 +fi + +echo "== 1/9: системные пакеты ==" +apt-get update +DEBIAN_FRONTEND=noninteractive apt-get install -y \ + haproxy nginx postgresql redis-server \ + python3 python3-venv python3-dev \ + libldap2-dev libsasl2-dev libssl-dev build-essential \ + rsync ufw + +echo "== 2/9: системный пользователь приложения ==" +if ! id -u "$APP_USER" >/dev/null 2>&1; then + useradd --system --home "$APP_DIR" --shell /usr/sbin/nologin "$APP_USER" +fi + +echo "== 3/9: код приложения ==" +mkdir -p "$APP_DIR" +rsync -a --delete "$REPO_ROOT/django_app/" "$APP_DIR/django_app/" +chown -R "$APP_USER:$APP_USER" "$APP_DIR" + +echo "== 4/9: виртуальное окружение Python ==" +if [[ ! -d "$APP_DIR/venv" ]]; then + python3 -m venv "$APP_DIR/venv" +fi +"$APP_DIR/venv/bin/pip" install --upgrade pip +"$APP_DIR/venv/bin/pip" install -r "$APP_DIR/django_app/requirements.txt" +chown -R "$APP_USER:$APP_USER" "$APP_DIR/venv" + +echo "== 5/9: конфигурация окружения ==" +mkdir -p "$ENV_DIR" +install -o root -g "$APP_USER" -m 640 "$ENV_FILE" "$ENV_DIR/admin-portal.env" + +echo "== 6/9: PostgreSQL — база и пользователь ==" +# Значения читаем из .env, чтобы не дублировать вручную +set -a; source "$ENV_DIR/admin-portal.env"; set +a +sudo -u postgres psql -tc "SELECT 1 FROM pg_roles WHERE rolname='${POSTGRES_USER}'" | grep -q 1 || \ + sudo -u postgres psql -c "CREATE ROLE ${POSTGRES_USER} LOGIN PASSWORD '${POSTGRES_PASSWORD}';" +sudo -u postgres psql -tc "SELECT 1 FROM pg_database WHERE datname='${POSTGRES_DB}'" | grep -q 1 || \ + sudo -u postgres psql -c "CREATE DATABASE ${POSTGRES_DB} OWNER ${POSTGRES_USER};" +systemctl enable --now postgresql redis-server + +echo "== 7/9: миграции и статика Django ==" +sudo -u "$APP_USER" bash -c "set -a; source $ENV_DIR/admin-portal.env; set +a; \ + $APP_DIR/venv/bin/python $APP_DIR/django_app/manage.py migrate --noinput && \ + $APP_DIR/venv/bin/python $APP_DIR/django_app/manage.py collectstatic --noinput" + +echo "== 8/9: systemd-юнит приложения ==" +install -m 644 "$REPO_ROOT/systemd/admin-portal.service" /etc/systemd/system/admin-portal.service +systemctl daemon-reload +systemctl enable --now admin-portal + +echo "== 9/9: HAProxy, Nginx (демо-бэкенды), фаервол ==" +install -m 644 "$REPO_ROOT/haproxy/haproxy.cfg" /etc/haproxy/haproxy.cfg +install -m 644 "$REPO_ROOT/haproxy/group_map.cfg" /etc/haproxy/group_map.cfg +mkdir -p /etc/haproxy/certs +chmod 700 /etc/haproxy/certs + +for res in resource1 resource2; do + mkdir -p "/var/www/admin-demo-${res}" + cp "$REPO_ROOT/backend_demo/${res}/index.html" "/var/www/admin-demo-${res}/index.html" + install -m 644 "$REPO_ROOT/backend_demo/${res}/nginx.conf" "/etc/nginx/sites-available/admin-demo-${res}" + ln -sf "/etc/nginx/sites-available/admin-demo-${res}" "/etc/nginx/sites-enabled/admin-demo-${res}" +done +rm -f /etc/nginx/sites-enabled/default +nginx -t && systemctl enable --now nginx && systemctl reload nginx + +ufw allow 80/tcp || true +ufw allow 443/tcp || true + +echo +echo "Готово. Дальше:" +echo " 1) положите TLS-сертификат в /etc/haproxy/certs/fqdn.pem" +echo " 2) haproxy -c -f /etc/haproxy/haproxy.cfg && systemctl reload haproxy" +echo " 3) создайте суперпользователя:" +echo " sudo -u ${APP_USER} bash -c 'set -a; source ${ENV_DIR}/admin-portal.env; set +a; ${APP_DIR}/venv/bin/python ${APP_DIR}/django_app/manage.py createsuperuser'" +echo " 4) наполните каталог ресурсов через /django-admin/ или sync_resources (см. README.md)"