mirror of
https://github.com/andrey271192/Domain_web.git
synced 2026-09-20 14:41:58 +00:00
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 <cursoragent@cursor.com>
This commit is contained in:
128
install.sh
128
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" <<EOF
|
||||
[Unit]
|
||||
Description=Domain Scanner (Next.js)
|
||||
After=network.target docker.service
|
||||
Wants=docker.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=${INSTALL_DIR}/.next/standalone
|
||||
EnvironmentFile=${INSTALL_DIR}/.env
|
||||
Environment=HOSTNAME=0.0.0.0
|
||||
Environment=PORT=${APP_PORT}
|
||||
Environment=NODE_ENV=production
|
||||
ExecStart=/usr/bin/node server.js
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
systemctl enable "${SERVICE_NAME}.service"
|
||||
systemctl restart "${SERVICE_NAME}.service"
|
||||
}
|
||||
|
||||
install_nginx() {
|
||||
@@ -138,10 +179,14 @@ EOF
|
||||
|
||||
verify() {
|
||||
log "Verifying deployment..."
|
||||
sleep 5
|
||||
sleep 4
|
||||
if ! systemctl is-active --quiet "${SERVICE_NAME}.service"; then
|
||||
systemctl status "${SERVICE_NAME}.service" --no-pager || true
|
||||
journalctl -u "${SERVICE_NAME}.service" -n 30 --no-pager || true
|
||||
exit 1
|
||||
fi
|
||||
if ! curl -fsS -o /dev/null "http://127.0.0.1:${APP_PORT}/api/health"; then
|
||||
echo "App health check failed on port ${APP_PORT}" >&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
|
||||
|
||||
Reference in New Issue
Block a user