Files

258 lines
8.0 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.
#!/bin/bash
# Интерактивный установщик Shop
# bash scripts/install.sh
# sudo bash scripts/install.sh (нативная установка на Ubuntu)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
# --- ввод ---
read_default() {
local prompt="$1"
local default="$2"
local value
if [ -n "$default" ]; then
read -rp "$prompt [$default]: " value
echo "${value:-$default}"
else
read -rp "$prompt: " value
echo "$value"
fi
}
read_secret() {
local prompt="$1"
local value
read -rsp "$prompt" value
echo ""
echo "$value"
}
read_secret_confirm() {
local prompt="$1"
local a b
while true; do
a=$(read_secret "$prompt")
b=$(read_secret "Повторите: ")
if [ "$a" = "$b" ]; then
echo "$a"
return
fi
echo "Пароли не совпадают. Попробуйте снова."
done
}
gen_secret() {
if command -v openssl >/dev/null; then
openssl rand -hex 32
else
head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n'
fi
}
# Безопасная запись значения в .env (одинарные кавычки)
env_quote() {
printf "'%s'" "$(printf '%s' "$1" | sed "s/'/'\\\\''/g")"
}
email_ok() {
[[ "$1" =~ ^[^\s@]+@[^\s@]+\.[^\s@]+$ ]]
}
# --- главная ---
clear 2>/dev/null || true
echo "============================================"
echo " Shop — интерактивная установка"
echo "============================================"
echo ""
# Каталог установки
if [ -f "$REPO_ROOT/package.json" ]; then
INSTALL_DIR=$(read_default "Каталог установки" "$REPO_ROOT")
else
INSTALL_DIR=$(read_default "Каталог установки" "/opt/shop")
if [ ! -f "$INSTALL_DIR/package.json" ]; then
GIT_URL=$(read_default "URL git-репозитория" "")
if [ -z "$GIT_URL" ]; then
echo "Ошибка: укажите URL репозитория или запустите установщик из клона."
exit 1
fi
echo "Клонирование $GIT_URL -> $INSTALL_DIR ..."
mkdir -p "$(dirname "$INSTALL_DIR")"
git clone "$GIT_URL" "$INSTALL_DIR"
fi
fi
cd "$INSTALL_DIR"
export SHOP_ROOT="$INSTALL_DIR"
# Режим
echo ""
echo "Способ установки:"
echo " 1) Docker Compose (PostgreSQL + приложение в контейнерах)"
echo " 2) Без Docker (Ubuntu: Node.js + PostgreSQL + systemd)"
echo ""
MODE=$(read_default "Выберите [1/2]" "1")
# Администратор
echo ""
echo "--- Администратор магазина (единственный admin) ---"
ADMIN_EMAIL=$(read_default "Email администратора" "admin@site.com")
while ! email_ok "$ADMIN_EMAIL"; do
echo "Некорректный email."
ADMIN_EMAIL=$(read_default "Email администратора" "admin@site.com")
done
ADMIN_NAME=$(read_default "Имя администратора" "Администратор")
ADMIN_PASSWORD=$(read_secret_confirm "Пароль администратора: ")
# База данных
echo ""
echo "--- PostgreSQL ---"
PG_USER=$(read_default "Пользователь БД" "shop")
PG_PASS=$(read_secret_confirm "Пароль БД: ")
PG_DB=$(read_default "Имя базы данных" "shop")
if [ "$MODE" = "1" ]; then
PG_HOST="postgres"
PG_PORT="5432"
APP_PORT=$(read_default "Порт сайта на хосте" "3000")
TRUST_PROXY="0"
echo ""
read -rp "Включить Caddy (HTTPS, порты 80/443)? [y/N]: " USE_CADDY
if [[ "${USE_CADDY,,}" == "y" || "${USE_CADDY,,}" == "yes" ]]; then
TRUST_PROXY="1"
USE_CADDY=1
else
USE_CADDY=0
fi
else
PG_HOST=$(read_default "Хост PostgreSQL" "127.0.0.1")
PG_PORT=$(read_default "Порт PostgreSQL" "5432")
APP_PORT="3000"
TRUST_PROXY=$(read_default "За reverse proxy (Caddy)? TRUST_PROXY [1/0]" "1")
USE_CADDY=0
fi
# Сайт и секрет
echo ""
echo "--- Прочие настройки ---"
if [ "$MODE" = "1" ] && [ "$USE_CADDY" = "1" ]; then
SITE_DEFAULT="https://shop.example.com"
else
SITE_DEFAULT="http://localhost:${APP_PORT}"
fi
SITE_URL=$(read_default "URL сайта (SITE_URL)" "$SITE_DEFAULT")
SESSION_SECRET=$(read_default "SESSION_SECRET (Enter = сгенерировать)" "")
SESSION_SECRET=${SESSION_SECRET:-$(gen_secret)}
echo ""
read -rp "Настроить SMTP для писем? [y/N]: " SET_SMTP
SMTP_BLOCK=""
if [[ "${SET_SMTP,,}" == "y" || "${SET_SMTP,,}" == "yes" ]]; then
SMTP_HOST=$(read_default "SMTP_HOST" "smtp.example.com")
SMTP_PORT=$(read_default "SMTP_PORT" "587")
SMTP_USER=$(read_default "SMTP_USER" "")
SMTP_PASS=$(read_secret "SMTP_PASS: ")
SMTP_FROM=$(read_default "SMTP_FROM" "shop@example.com")
SMTP_BLOCK="# SMTP
SMTP_HOST=${SMTP_HOST}
SMTP_PORT=${SMTP_PORT}
SMTP_SECURE=false
SMTP_USER=${SMTP_USER}
SMTP_PASS=${SMTP_PASS}
SMTP_FROM=${SMTP_FROM}
"
fi
DATABASE_URL="postgresql://${PG_USER}:${PG_PASS}@${PG_HOST}:${PG_PORT}/${PG_DB}"
# --- запись .env ---
ENV_FILE="$INSTALL_DIR/.env"
APP_HOST=$([ "$MODE" = "1" ] && echo "0.0.0.0" || echo "127.0.0.1")
{
echo "# Создано scripts/install.sh $(date -Iseconds)"
echo ""
echo "PORT=${APP_PORT}"
echo "HOST=${APP_HOST}"
echo "NODE_ENV=production"
echo "TRUST_PROXY=${TRUST_PROXY}"
echo "SESSION_SECRET=$(env_quote "$SESSION_SECRET")"
echo ""
echo "ADMIN_EMAIL=$(env_quote "$ADMIN_EMAIL")"
echo "ADMIN_PASSWORD=$(env_quote "$ADMIN_PASSWORD")"
echo "ADMIN_NAME=$(env_quote "$ADMIN_NAME")"
echo ""
echo "SITE_URL=$(env_quote "$SITE_URL")"
echo ""
if [ -n "$SMTP_BLOCK" ]; then
echo "$SMTP_BLOCK"
fi
echo "# PostgreSQL"
echo "POSTGRES_USER=$(env_quote "$PG_USER")"
echo "POSTGRES_PASSWORD=$(env_quote "$PG_PASS")"
echo "POSTGRES_DB=$(env_quote "$PG_DB")"
echo "DATABASE_URL=$(env_quote "$DATABASE_URL")"
echo "PGHOST=$(env_quote "$PG_HOST")"
echo "PGPORT=${PG_PORT}"
echo "PGUSER=$(env_quote "$PG_USER")"
echo "PGPASSWORD=$(env_quote "$PG_PASS")"
echo "PGDATABASE=$(env_quote "$PG_DB")"
} > "$ENV_FILE"
chmod 600 "$ENV_FILE" 2>/dev/null || true
echo ""
echo "Сохранено: $ENV_FILE"
# --- установка ---
echo ""
if [ "$MODE" = "1" ]; then
echo "=== Установка через Docker ==="
if ! command -v docker >/dev/null; then
echo "Ошибка: Docker не установлен. Установите Docker и повторите."
exit 1
fi
if ! docker compose version >/dev/null 2>&1; then
echo "Ошибка: нужен Docker Compose v2 (docker compose)."
exit 1
fi
COMPOSE_CMD=(docker compose)
if [ "$USE_CADDY" = "1" ]; then
echo "Запуск: postgres + app + caddy ..."
"${COMPOSE_CMD[@]}" --profile proxy up -d --build
else
echo "Запуск: postgres + app ..."
"${COMPOSE_CMD[@]}" up -d --build
fi
echo "Ожидание health..."
sleep 5
curl -sf "http://127.0.0.1:${APP_PORT}/health" && echo "" || echo "Проверьте: docker compose logs app"
else
echo "=== Установка без Docker (Ubuntu) ==="
if [ "$(id -u)" -ne 0 ]; then
echo "Запустите с root: sudo bash scripts/install.sh"
exit 1
fi
bash "$SCRIPT_DIR/install-postgresql-ubuntu.sh"
export DB_USER="$PG_USER" DB_PASS="$PG_PASS" DB_NAME="$PG_DB"
bash "$SCRIPT_DIR/setup-postgres-ubuntu.sh"
npm install --omit=dev
bash "$SCRIPT_DIR/install-shop-service.sh"
fi
echo ""
echo "============================================"
echo " Установка завершена"
echo "============================================"
echo " Каталог: $INSTALL_DIR"
echo " Сайт: $SITE_URL"
echo " Админ: $ADMIN_EMAIL"
if [ "$MODE" = "1" ]; then
echo " Порт: $APP_PORT"
echo " Логи: docker compose -f $INSTALL_DIR/docker-compose.yml logs -f"
else
echo " Служба: systemctl status shop"
echo " Health: curl http://127.0.0.1:3000/health"
fi
echo " Обновление: bash $INSTALL_DIR/scripts/server-update.sh"
echo "============================================"