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
|
#!/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
|
set -euo pipefail
|
||||||
|
|
||||||
REPO_URL="${DOMAIN_SCANNER_REPO_URL:-https://github.com/andrey271192/Domain_web.git}"
|
REPO_URL="${DOMAIN_SCANNER_REPO_URL:-https://github.com/andrey271192/Domain_web.git}"
|
||||||
BRANCH="${DOMAIN_SCANNER_BRANCH:-main}"
|
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"
|
SERVICE_NAME="domain-scanner"
|
||||||
NGINX_SITE="domain-scanner"
|
NGINX_SITE="domain-scanner"
|
||||||
APP_PORT="${DOMAIN_SCANNER_PORT:-3000}"
|
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
|
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() {
|
install_docker() {
|
||||||
if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then
|
if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then
|
||||||
log "Docker already installed"
|
log "Docker already installed"
|
||||||
return
|
else
|
||||||
|
log "Installing Docker..."
|
||||||
|
curl -fsSL https://get.docker.com | sh
|
||||||
fi
|
fi
|
||||||
log "Installing Docker..."
|
systemctl enable docker.socket docker.service 2>/dev/null || true
|
||||||
curl -fsSL https://get.docker.com | sh
|
systemctl start docker.socket 2>/dev/null || true
|
||||||
systemctl enable docker.socket docker.service
|
systemctl start docker.service 2>/dev/null || true
|
||||||
systemctl start docker.socket
|
|
||||||
systemctl start docker.service
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_legacy() {
|
stop_legacy() {
|
||||||
@@ -46,6 +57,7 @@ stop_legacy() {
|
|||||||
rm -f "/etc/systemd/system/${LEGACY_SERVICE}.service"
|
rm -f "/etc/systemd/system/${LEGACY_SERVICE}.service"
|
||||||
rm -f "/etc/nginx/sites-enabled/${LEGACY_NGINX}"
|
rm -f "/etc/nginx/sites-enabled/${LEGACY_NGINX}"
|
||||||
rm -f "/etc/nginx/sites-available/${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
|
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_SECRET=.*|NEXTAUTH_SECRET=${secret}|" .env
|
||||||
sed -i "s|^NEXTAUTH_URL=.*|NEXTAUTH_URL=http://${ip}|" .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
|
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}"
|
cd "${INSTALL_DIR}"
|
||||||
export PORT="${APP_PORT}"
|
docker compose up -d postgres redis
|
||||||
AVAIL_KB=$(df -k "${INSTALL_DIR}" | awk 'NR==2 {print $4}')
|
for i in $(seq 1 30); do
|
||||||
if [[ "${AVAIL_KB:-0}" -lt 2500000 ]]; then
|
if docker compose exec -T postgres pg_isready -U scanner -d domain_scanner >/dev/null 2>&1; then
|
||||||
log "Low disk — Node-native deploy..."
|
break
|
||||||
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
|
|
||||||
fi
|
fi
|
||||||
docker compose up -d
|
sleep 2
|
||||||
docker compose exec -T web npx prisma db push
|
done
|
||||||
else
|
}
|
||||||
if ! docker-compose build 2>&1; then
|
|
||||||
bash "${INSTALL_DIR}/scripts/install-node.sh"
|
build_app() {
|
||||||
return
|
log "Building Next.js app on host..."
|
||||||
fi
|
cd "${INSTALL_DIR}"
|
||||||
docker-compose up -d
|
export NODE_ENV=production
|
||||||
docker-compose exec -T web npx prisma db push
|
npm ci
|
||||||
fi
|
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() {
|
install_nginx() {
|
||||||
@@ -138,10 +179,14 @@ EOF
|
|||||||
|
|
||||||
verify() {
|
verify() {
|
||||||
log "Verifying deployment..."
|
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
|
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
|
echo "Health check failed on port ${APP_PORT}" >&2
|
||||||
cd "${INSTALL_DIR}" && docker compose logs --tail=40 web 2>/dev/null || true
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
local title
|
local title
|
||||||
@@ -150,22 +195,21 @@ verify() {
|
|||||||
echo "ERROR: GeoExport mirror still served — aborting" >&2
|
echo "ERROR: GeoExport mirror still served — aborting" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
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
|
local ip
|
||||||
ip="$(hostname -I | awk '{print $1}')"
|
ip="$(hostname -I | awk '{print $1}')"
|
||||||
log "Done. Domain Scanner: http://${ip}/"
|
log "Done. Domain Scanner: http://${ip}/"
|
||||||
log "Title check: ${title:-ok}"
|
log "Title: ${title:-Domain Scanner}"
|
||||||
}
|
}
|
||||||
|
|
||||||
need_root
|
need_root
|
||||||
install_packages
|
install_packages
|
||||||
|
install_node
|
||||||
install_docker
|
install_docker
|
||||||
stop_legacy
|
stop_legacy
|
||||||
clone_or_update
|
clone_or_update
|
||||||
setup_env
|
setup_env
|
||||||
deploy_compose
|
deploy_data_services
|
||||||
|
build_app
|
||||||
|
install_systemd
|
||||||
install_nginx
|
install_nginx
|
||||||
verify
|
verify
|
||||||
|
|||||||
Reference in New Issue
Block a user