diff --git a/UNICORN_FINAL/scripts/fix-server.sh b/UNICORN_FINAL/scripts/fix-server.sh index aef3a35e..c29f7995 100755 --- a/UNICORN_FINAL/scripts/fix-server.sh +++ b/UNICORN_FINAL/scripts/fix-server.sh @@ -318,27 +318,41 @@ ENVFILE if [ "$PORT_IN_USE" -eq 1 ]; then ok "Portul ${NODE_PORT} este deja ocupat (Node.js probabil rulează) ✓" else - warn "Portul ${NODE_PORT} nu este ascultat. Se (re)pornesc procesele PM2..." + warn "Portul ${NODE_PORT} nu este ascultat. Se încearcă (re)pornirea serviciului..." cd "$DEPLOY_PATH" - # Clean PM2 start (vezi memory: restart eșuează când procesele au crash) - pm2 stop all 2>/dev/null || true - pm2 delete all 2>/dev/null || true - - if [ -f "$DEPLOY_PATH/ecosystem.config.js" ]; then - pm2 start ecosystem.config.js - fixed "PM2 pornit din ecosystem.config.js" - elif [ -f "$DEPLOY_PATH/backend/index.js" ]; then - pm2 start backend/index.js \ - --name unicorn-backend \ - --env production \ - -- PORT="${NODE_PORT}" - fixed "PM2 pornit direct din backend/index.js" - else - ko "Niciun punct de intrare găsit (ecosystem.config.js sau backend/index.js)" + # Încearcă mai întâi unicorn.service (dacă există) + if systemctl is-enabled --quiet unicorn.service 2>/dev/null; then + systemctl restart unicorn.service 2>/dev/null || true + sleep 3 + if ss -tlnp 2>/dev/null | grep -q ":${NODE_PORT}[[:space:]]"; then + fixed "unicorn.service (re)pornit cu succes" + PORT_IN_USE=1 + else + warn "unicorn.service nu a pornit backend-ul. Se trece la PM2..." + fi fi - pm2 save + # Fallback: PM2 clean start + if [ "$PORT_IN_USE" -eq 0 ]; then + pm2 stop all 2>/dev/null || true + pm2 delete all 2>/dev/null || true + + if [ -f "$DEPLOY_PATH/ecosystem.config.js" ]; then + pm2 start ecosystem.config.js + fixed "PM2 pornit din ecosystem.config.js" + elif [ -f "$DEPLOY_PATH/backend/index.js" ]; then + pm2 start backend/index.js \ + --name unicorn-backend \ + --env production \ + -- PORT="${NODE_PORT}" + fixed "PM2 pornit direct din backend/index.js" + else + ko "Niciun punct de intrare găsit (ecosystem.config.js sau backend/index.js)" + fi + + pm2 save + fi fi # 3g. Activare PM2 la boot @@ -470,6 +484,15 @@ else echo -e " ${YELLOW}⚠️ SSL Certbot → fără certificat (HTTP only)${NC}" fi +# unicorn.service +if systemctl is-active --quiet unicorn.service 2>/dev/null; then + echo -e " ${GREEN}✅ unicorn.service → ACTIV${NC}" +elif systemctl is-enabled --quiet unicorn.service 2>/dev/null; then + echo -e " ${GREEN}✅ unicorn.service → enabled (PM2 gestionează procesele)${NC}" +else + echo -e " ${YELLOW}⚠️ unicorn.service → neinstalat (rulați setup-systemd.sh)${NC}" +fi + echo "" echo -e "${BOLD}Sumar verificări:${NC}" echo -e " ${GREEN}Trecut: $PASS${NC}" diff --git a/UNICORN_FINAL/scripts/setup-server.sh b/UNICORN_FINAL/scripts/setup-server.sh index 97113208..90748be7 100755 --- a/UNICORN_FINAL/scripts/setup-server.sh +++ b/UNICORN_FINAL/scripts/setup-server.sh @@ -343,11 +343,159 @@ else warn "DEPLOY_PATH=$DEPLOY_PATH nu există — PM2 nu a fost pornit" fi +# ============================================================================= +# ETAPA 5.5 — Creare și activare unicorn.service (systemd) +# ============================================================================= +step "5.5. unicorn.service — systemd" + +# Dacă există setup-systemd.sh, delegăm configurarea acolo +if [ -f "${DEPLOY_PATH}/scripts/setup-systemd.sh" ]; then + info "Se rulează setup-systemd.sh pentru a crea unicorn.service..." + bash "${DEPLOY_PATH}/scripts/setup-systemd.sh" "$DEPLOY_PATH" + ok "setup-systemd.sh executat cu succes" +else + # Fallback inline: creare unicorn.service direct + NODE_BIN_PATH="$(command -v node 2>/dev/null || echo '/usr/bin/node')" + PM2_BIN_PATH="$(command -v pm2 2>/dev/null || echo '/usr/local/bin/pm2')" + # Validate that the binaries are actually present at the resolved paths + [ -x "$NODE_BIN_PATH" ] || die "Node.js nu a fost găsit (căutat: $NODE_BIN_PATH). Instalați Node.js și reîncercați." + [ -x "$PM2_BIN_PATH" ] || die "PM2 nu a fost găsit (căutat: $PM2_BIN_PATH). Rulați: npm install -g pm2" + RUN_USER_SVC="${SUDO_USER:-root}" + PM2_HOME_SVC="$(eval echo ~"$RUN_USER_SVC")/.pm2" + NODE_DIR_SVC="$(dirname "$NODE_BIN_PATH")" + + # Serviciu primar PM2 (resurrect la boot) + cat > "/etc/systemd/system/pm2-${RUN_USER_SVC}.service" < /etc/systemd/system/unicorn.service </dev/null | grep -q ":${NODE_PORT}[[:space:]]" && PORT_SVC_UP=1 || true +if [ "$PORT_SVC_UP" -eq 0 ]; then + info "Backend-ul nu ascultă pe portul ${NODE_PORT} — se pornește unicorn.service..." + systemctl start unicorn.service 2>/dev/null || true +fi + +# Verificare finală serviciu +if systemctl is-active --quiet unicorn.service 2>/dev/null; then + ok "unicorn.service → ACTIV" +elif systemctl is-enabled --quiet unicorn.service 2>/dev/null; then + ok "unicorn.service → enabled (PM2 gestionează procesele activ)" +else + warn "unicorn.service nu este activ — verifică: systemctl status unicorn" +fi + # ============================================================================= # ETAPA 6 — SSL cu Certbot (Let's Encrypt) # ============================================================================= step "6. SSL — Certbot Let's Encrypt" +# ── Validare DNS înainte de Certbot ────────────────────────────────────────── +dns_ok=1 +if [ "$SKIP_SSL" != "1" ]; then + info "Verificare DNS pentru $DOMAIN și www.$DOMAIN..." + + # Obține IP-ul public al serverului curent + SERVER_IP="" + for _src in \ + "https://api.ipify.org" \ + "https://ifconfig.me" \ + "https://ipecho.net/plain" \ + "https://icanhazip.com"; do + SERVER_IP=$(curl -fsSL --max-time 5 "$_src" 2>/dev/null | tr -d '[:space:]') || true + [ -n "$SERVER_IP" ] && break + done + + if [ -z "$SERVER_IP" ]; then + warn "Nu s-a putut determina IP-ul public al serverului. Se verifică DNS fără comparație." + else + info "IP server: $SERVER_IP" + fi + + for _host in "$DOMAIN" "www.${DOMAIN}"; do + RESOLVED_IP=$(getent hosts "$_host" 2>/dev/null | awk '{print $1; exit}' || \ + host "$_host" 2>/dev/null | awk '/has address/{print $4; exit}' || \ + dig +short "$_host" A 2>/dev/null | grep -E '^[0-9]+\.' | head -1 || echo "") + + if [ -z "$RESOLVED_IP" ]; then + warn "DNS: $_host nu se poate rezolva — recordul A lipsește sau nu a propagat." + dns_ok=0 + elif [ -n "$SERVER_IP" ] && [ "$RESOLVED_IP" != "$SERVER_IP" ]; then + warn "DNS: $_host → $RESOLVED_IP ≠ IP server ($SERVER_IP)" + warn "Adaugă un record A: $_host → $SERVER_IP" + dns_ok=0 + else + ok "DNS: $_host → $RESOLVED_IP ✓" + fi + done + + if [ "$dns_ok" -eq 0 ]; then + SKIP_SSL=1 + warn "DNS-ul nu pointează corect la acest server." + warn "SKIP_SSL setat automat la 1 — certbot ar eșua și ar bloca instalarea." + info "Acțiune necesară: configurează recordurile A în panoul DNS:" + info " $DOMAIN → $SERVER_IP" + info " www.$DOMAIN → $SERVER_IP" + info "Așteptați propagarea DNS (5–60 minute) apoi rulați:" + info " certbot --nginx -d ${DOMAIN} -d www.${DOMAIN} --non-interactive --agree-tos -m ${ADMIN_EMAIL}" + else + ok "DNS validat cu succes — certbot poate obține certificatul." + fi +fi + if [ "$SKIP_SSL" = "1" ]; then warn "SKIP_SSL=1 — obținere certificat SSL sărită" info "Rulează manual când DNS-ul domeniului pointează la acest server:" @@ -495,6 +643,15 @@ else echo -e " ${YELLOW}⚠️ SSL Certbot → fără certificat (HTTP only)${NC}" fi +# unicorn.service +if systemctl is-active --quiet unicorn.service 2>/dev/null; then + echo -e " ${GREEN}✅ unicorn.service → ACTIV${NC}" +elif systemctl is-enabled --quiet unicorn.service 2>/dev/null; then + echo -e " ${GREEN}✅ unicorn.service → enabled (PM2 gestionează procesele)${NC}" +else + echo -e " ${YELLOW}⚠️ unicorn.service → neinstalat${NC}" +fi + echo "" echo -e "${BOLD}URL-uri:${NC}" echo -e " ${CYAN}http://${DOMAIN}${NC}" @@ -504,6 +661,7 @@ echo -e " ${CYAN}http://${DOMAIN}${NC}" echo "" echo -e "${BOLD}Comenzi utile:${NC}" echo " pm2 list && pm2 logs" +echo " systemctl status unicorn" echo " systemctl status nginx" echo " ufw status verbose" echo " curl -I http://localhost:${NODE_PORT}/api/health"