From 9c7bd392e9dd60df796c8c3c8443d9ebb2a3b168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=91=D0=BE=D0=B1?= =?UTF-8?q?=D1=8B=D1=80=D0=B5=D0=B2?= Date: Sun, 24 May 2026 22:22:55 +0300 Subject: [PATCH] fix(install): lite deploy for small VPS disks Run Postgres/Redis in Docker and build Next.js on host to avoid image build exhausting 10GB root volumes. Co-authored-by: Cursor --- install.sh | 128 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 86 insertions(+), 42 deletions(-) diff --git a/install.sh b/install.sh index 33e1aa3..f8b1130 100755 --- a/install.sh +++ b/install.sh @@ -1,10 +1,11 @@ #!/usr/bin/env bash -# Domain Scanner — one-command VPS install (Docker Compose + nginx) +# Domain Scanner — VPS install (Postgres/Redis in Docker, Next.js on host) +# Full `docker compose up` (web image) needs ~4GB free disk; this script uses the lite path. set -euo pipefail REPO_URL="${DOMAIN_SCANNER_REPO_URL:-https://github.com/andrey271192/Domain_web.git}" BRANCH="${DOMAIN_SCANNER_BRANCH:-main}" -INSTALL_DIR="${DOMAIN_SCANNER_INSTALL_DIR:-/opt/domain_web}" +INSTALL_DIR="${DOMAIN_SCANNER_INSTALL_DIR:-/opt/domain-scanner}" SERVICE_NAME="domain-scanner" NGINX_SITE="domain-scanner" APP_PORT="${DOMAIN_SCANNER_PORT:-3000}" @@ -27,16 +28,26 @@ install_packages() { apt-get install -y -qq curl ca-certificates git nginx openssl >/dev/null } +install_node() { + if command -v node >/dev/null 2>&1 && [[ "$(node -p 'process.versions.node.split(".")[0]')" -ge 20 ]]; then + log "Node $(node -v) already installed" + return + fi + log "Installing Node.js 22..." + curl -fsSL https://deb.nodesource.com/setup_22.x | bash - + apt-get install -y -qq nodejs >/dev/null +} + install_docker() { if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then log "Docker already installed" - return + else + log "Installing Docker..." + curl -fsSL https://get.docker.com | sh fi - log "Installing Docker..." - curl -fsSL https://get.docker.com | sh - systemctl enable docker.socket docker.service - systemctl start docker.socket - systemctl start docker.service + systemctl enable docker.socket docker.service 2>/dev/null || true + systemctl start docker.socket 2>/dev/null || true + systemctl start docker.service 2>/dev/null || true } stop_legacy() { @@ -46,6 +57,7 @@ stop_legacy() { rm -f "/etc/systemd/system/${LEGACY_SERVICE}.service" rm -f "/etc/nginx/sites-enabled/${LEGACY_NGINX}" rm -f "/etc/nginx/sites-available/${LEGACY_NGINX}" + rm -rf /opt/domain_web 2>/dev/null || true systemctl daemon-reload 2>/dev/null || true } @@ -73,35 +85,64 @@ setup_env() { sed -i "s|^NEXTAUTH_SECRET=.*|NEXTAUTH_SECRET=${secret}|" .env sed -i "s|^NEXTAUTH_URL=.*|NEXTAUTH_URL=http://${ip}|" .env sed -i "s|^NEXT_PUBLIC_APP_URL=.*|NEXT_PUBLIC_APP_URL=http://${ip}|" .env - export PORT="${APP_PORT}" + sed -i "s|^DATABASE_URL=.*|DATABASE_URL=postgresql://scanner:scanner@127.0.0.1:5432/domain_scanner?schema=public|" .env + sed -i "s|^REDIS_URL=.*|REDIS_URL=redis://127.0.0.1:6379|" .env } -deploy_compose() { +deploy_data_services() { + log "Starting Postgres and Redis (Docker)..." cd "${INSTALL_DIR}" - export PORT="${APP_PORT}" - AVAIL_KB=$(df -k "${INSTALL_DIR}" | awk 'NR==2 {print $4}') - if [[ "${AVAIL_KB:-0}" -lt 2500000 ]]; then - log "Low disk — Node-native deploy..." - bash "${INSTALL_DIR}/scripts/install-node.sh" - return - fi - log "Building Docker stack..." - if docker compose version >/dev/null 2>&1; then - if ! docker compose build 2>&1; then - log "Docker build failed — Node-native deploy..." - bash "${INSTALL_DIR}/scripts/install-node.sh" - return + docker compose up -d postgres redis + for i in $(seq 1 30); do + if docker compose exec -T postgres pg_isready -U scanner -d domain_scanner >/dev/null 2>&1; then + break fi - docker compose up -d - docker compose exec -T web npx prisma db push - else - if ! docker-compose build 2>&1; then - bash "${INSTALL_DIR}/scripts/install-node.sh" - return - fi - docker-compose up -d - docker-compose exec -T web npx prisma db push - fi + sleep 2 + done +} + +build_app() { + log "Building Next.js app on host..." + cd "${INSTALL_DIR}" + export NODE_ENV=production + npm ci + npx prisma generate + npx prisma db push + npm run build + rm -rf node_modules + npm ci --omit=dev + npx prisma generate + cp -r .next/static .next/standalone/.next/static + cp -r public .next/standalone/public + journalctl --vacuum-size=80M 2>/dev/null || true + apt-get clean 2>/dev/null || true +} + +install_systemd() { + log "Installing systemd unit (${SERVICE_NAME})..." + cat >"/etc/systemd/system/${SERVICE_NAME}.service" <&2 - cd "${INSTALL_DIR}" && docker compose logs --tail=40 web 2>/dev/null || true + echo "Health check failed on port ${APP_PORT}" >&2 exit 1 fi local title @@ -150,22 +195,21 @@ verify() { echo "ERROR: GeoExport mirror still served — aborting" >&2 exit 1 fi - if ! curl -fsS -o /dev/null "http://127.0.0.1/"; then - echo "nginx not serving on :80" >&2 - exit 1 - fi local ip ip="$(hostname -I | awk '{print $1}')" log "Done. Domain Scanner: http://${ip}/" - log "Title check: ${title:-ok}" + log "Title: ${title:-Domain Scanner}" } need_root install_packages +install_node install_docker stop_legacy clone_or_update setup_env -deploy_compose +deploy_data_services +build_app +install_systemd install_nginx verify