deploy.sh: update for new auth structure (lib/, data/, better-sqlite3, pm2 reload)
This commit is contained in:
parent
8e98b3974a
commit
596bf0bce0
1 changed files with 68 additions and 48 deletions
116
deploy.sh
116
deploy.sh
|
|
@ -7,11 +7,11 @@
|
|||
# Apache (port 80) → reverse proxy → Node.js (port 3000)
|
||||
#
|
||||
# Prerequisites (do these manually before running this script):
|
||||
# git clone git@bitbucket.org:zlalani/3m-portal.git /opt/3m-portal
|
||||
# Upload new code to the server (rsync or git pull), then:
|
||||
#
|
||||
# Usage:
|
||||
# sudo bash /opt/3m-portal/deploy.sh # first-time install
|
||||
# sudo bash /opt/3m-portal/deploy.sh --update # reload after git pull
|
||||
# sudo bash /opt/3m-portal/deploy.sh --update # reload after code update
|
||||
# =============================================================
|
||||
set -euo pipefail
|
||||
|
||||
|
|
@ -32,7 +32,8 @@ UPDATE_ONLY=false
|
|||
|
||||
# ── 0. Checks ─────────────────────────────────────────────────
|
||||
[[ $EUID -ne 0 ]] && error "Run as root: sudo bash deploy.sh"
|
||||
[[ ! -f "$APP_DIR/server.js" ]] && error "Code not found at $APP_DIR. Clone the repo first:\n git clone git@bitbucket.org:zlalani/3m-portal.git $APP_DIR"
|
||||
[[ ! -f "$APP_DIR/server.js" ]] && error "Code not found at $APP_DIR. Upload the code first."
|
||||
[[ ! -d "$APP_DIR/lib" ]] && error "lib/ directory missing — make sure the full codebase is uploaded."
|
||||
|
||||
# ── 1. Node.js + build tools ──────────────────────────────────
|
||||
if ! $UPDATE_ONLY; then
|
||||
|
|
@ -44,7 +45,7 @@ if ! $UPDATE_ONLY; then
|
|||
fi
|
||||
info "Node.js $(node -v), npm $(npm -v)"
|
||||
|
||||
section "Build tools (for better-sqlite3 native module)"
|
||||
section "Build tools (required for better-sqlite3 native module)"
|
||||
apt-get install -y build-essential python3 make g++
|
||||
info "Build tools installed"
|
||||
fi
|
||||
|
|
@ -75,7 +76,7 @@ section "Data directory"
|
|||
mkdir -p "$APP_DIR/data"
|
||||
chown "$APP_USER":"$APP_USER" "$APP_DIR/data"
|
||||
chmod 700 "$APP_DIR/data"
|
||||
info "Data directory: $APP_DIR/data"
|
||||
info "Data directory: $APP_DIR/data (owner: $APP_USER, mode: 700)"
|
||||
|
||||
# ── 4. .env ───────────────────────────────────────────────────
|
||||
section ".env"
|
||||
|
|
@ -93,15 +94,15 @@ COOKIE_SECURE=true
|
|||
SESSION_TTL_MS=28800000
|
||||
INITIAL_ADMINS=[{"email":"CHANGE_ME","one2editUsername":"CHANGE_ME","password":"CHANGE_ME"}]
|
||||
MAILGUN_API_KEY=CHANGE_ME
|
||||
MAILGUN_DOMAIN=CHANGE_ME
|
||||
MAILGUN_FROM=CHANGE_ME
|
||||
MAILGUN_DOMAIN=mg.oliver.solutions
|
||||
MAILGUN_FROM=noreply@mg.oliver.solutions
|
||||
EOF
|
||||
warn "──────────────────────────────────────────────────"
|
||||
warn "Edit all values now: nano $ENV_FILE"
|
||||
warn "──────────────────────────────────────────────────"
|
||||
read -rp "Press Enter after updating .env to continue..."
|
||||
else
|
||||
info ".env already exists — skipping"
|
||||
info ".env exists"
|
||||
fi
|
||||
|
||||
if grep -q "CHANGE_ME" "$ENV_FILE"; then
|
||||
|
|
@ -110,32 +111,51 @@ fi
|
|||
|
||||
# ── 5. Permissions ────────────────────────────────────────────
|
||||
section "Permissions"
|
||||
# Own all app files as nodeapp, then lock down .env and data
|
||||
chown -R "$APP_USER":"$APP_USER" "$APP_DIR"
|
||||
chmod 600 "$ENV_FILE"
|
||||
info "Owner: $APP_USER, .env: 600"
|
||||
# Re-apply data dir restriction (chown -R sets ownership but not mode)
|
||||
chmod 700 "$APP_DIR/data"
|
||||
info "Owner: $APP_USER, .env: 600, data/: 700"
|
||||
|
||||
# ── 5a. npm install ───────────────────────────────────────────
|
||||
section "npm install"
|
||||
cd "$APP_DIR" && sudo -u "$APP_USER" npm install --omit=dev
|
||||
info "Dependencies installed"
|
||||
cd "$APP_DIR" && HOME="$APP_DIR" sudo -u "$APP_USER" npm install --omit=dev
|
||||
info "Dependencies installed (including better-sqlite3 native build)"
|
||||
|
||||
# ── 6. PM2 process ────────────────────────────────────────────
|
||||
section "PM2 process"
|
||||
pm2 stop 3m-portal 2>/dev/null || true
|
||||
pm2 delete 3m-portal 2>/dev/null || true
|
||||
if $UPDATE_ONLY; then
|
||||
# Reload picks up new code + fresh .env without dropping existing sessions
|
||||
if pm2 describe 3m-portal &>/dev/null; then
|
||||
pm2 reload 3m-portal --update-env
|
||||
info "PM2 reloaded with updated env"
|
||||
else
|
||||
warn "PM2 process not found — starting fresh"
|
||||
pm2 start "$APP_DIR/server.js" \
|
||||
--name 3m-portal \
|
||||
--user "$APP_USER" \
|
||||
--log /var/log/3m-portal.log \
|
||||
--restart-delay 3000 \
|
||||
--max-restarts 10
|
||||
fi
|
||||
else
|
||||
pm2 stop 3m-portal 2>/dev/null || true
|
||||
pm2 delete 3m-portal 2>/dev/null || true
|
||||
|
||||
pm2 start "$APP_DIR/server.js" \
|
||||
--name 3m-portal \
|
||||
--user "$APP_USER" \
|
||||
--log /var/log/3m-portal.log \
|
||||
--restart-delay 3000 \
|
||||
--max-restarts 10
|
||||
pm2 start "$APP_DIR/server.js" \
|
||||
--name 3m-portal \
|
||||
--user "$APP_USER" \
|
||||
--log /var/log/3m-portal.log \
|
||||
--restart-delay 3000 \
|
||||
--max-restarts 10
|
||||
|
||||
env PATH="$PATH:/usr/bin" pm2 startup systemd -u "$APP_USER" --hp "$APP_DIR" \
|
||||
| tail -1 | bash || warn "Run 'pm2 startup' manually if autostart is needed"
|
||||
fi
|
||||
|
||||
pm2 save
|
||||
info "PM2 process started"
|
||||
|
||||
env PATH="$PATH:/usr/bin" pm2 startup systemd -u "$APP_USER" --hp "$APP_DIR" \
|
||||
| tail -1 | bash || warn "Run 'pm2 startup' manually if autostart is needed"
|
||||
info "PM2 state saved"
|
||||
|
||||
# ── 7. Apache modules ─────────────────────────────────────────
|
||||
if ! $UPDATE_ONLY; then
|
||||
|
|
@ -145,23 +165,20 @@ if ! $UPDATE_ONLY; then
|
|||
fi
|
||||
|
||||
# ── 8. Apache virtual host ────────────────────────────────────
|
||||
section "Apache vhost"
|
||||
if ! $UPDATE_ONLY; then
|
||||
section "Apache vhost"
|
||||
|
||||
if [ -f "$APACHE_CONF" ]; then
|
||||
cp "$APACHE_CONF" "${APACHE_CONF}.bak.$(date +%Y%m%d%H%M%S)"
|
||||
info "Backed up existing config"
|
||||
fi
|
||||
if [ -f "$APACHE_CONF" ]; then
|
||||
cp "$APACHE_CONF" "${APACHE_CONF}.bak.$(date +%Y%m%d%H%M%S)"
|
||||
info "Backed up existing config"
|
||||
fi
|
||||
|
||||
cat > "$APACHE_CONF" << EOF
|
||||
cat > "$APACHE_CONF" << EOF
|
||||
# 3M OMG Portal — Apache reverse proxy to Node.js
|
||||
#
|
||||
# SSL is terminated at the load balancer.
|
||||
# This server receives plain HTTP on port 80 from the LB
|
||||
# and proxies it to Node.js on port ${NODE_PORT}.
|
||||
#
|
||||
# App: ${APP_DIR}
|
||||
# Note: /var/vhosts/${DOMAIN}/htdocs exists (created by DevOps)
|
||||
# but is intentionally unused — all traffic goes to Node.js.
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerName ${DOMAIN}
|
||||
|
|
@ -181,17 +198,18 @@ cat > "$APACHE_CONF" << EOF
|
|||
</VirtualHost>
|
||||
EOF
|
||||
|
||||
info "Apache config written: $APACHE_CONF"
|
||||
info "Apache config written: $APACHE_CONF"
|
||||
|
||||
# ── 9. Enable site & reload Apache ────────────────────────────
|
||||
section "Apache reload"
|
||||
a2ensite "${DOMAIN}.conf" 2>/dev/null || true
|
||||
# ── 9. Enable site & reload Apache ────────────────────────────
|
||||
section "Apache reload"
|
||||
a2ensite "${DOMAIN}.conf" 2>/dev/null || true
|
||||
|
||||
if apache2ctl configtest 2>&1; then
|
||||
systemctl reload apache2
|
||||
info "Apache reloaded"
|
||||
else
|
||||
error "Apache config test failed — check $APACHE_CONF"
|
||||
if apache2ctl configtest 2>&1; then
|
||||
systemctl reload apache2
|
||||
info "Apache reloaded"
|
||||
else
|
||||
error "Apache config test failed — check $APACHE_CONF"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── 10. Smoke test ────────────────────────────────────────────
|
||||
|
|
@ -203,10 +221,12 @@ else
|
|||
error "Node.js not responding. Check logs: pm2 logs 3m-portal"
|
||||
fi
|
||||
|
||||
if curl -sf "http://127.0.0.1/" -o /dev/null; then
|
||||
info "Apache proxy responding on port 80"
|
||||
else
|
||||
warn "Apache not responding on port 80 — check: systemctl status apache2"
|
||||
if ! $UPDATE_ONLY; then
|
||||
if curl -sf "http://127.0.0.1/" -o /dev/null; then
|
||||
info "Apache proxy responding on port 80"
|
||||
else
|
||||
warn "Apache not responding on port 80 — check: systemctl status apache2"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── Done ──────────────────────────────────────────────────────
|
||||
|
|
@ -216,7 +236,7 @@ echo -e "${GREEN}║ Deploy complete! ║${N
|
|||
echo -e "${GREEN}║ ║${NC}"
|
||||
echo -e "${GREEN}║ Portal: https://${DOMAIN} ║${NC}"
|
||||
echo -e "${GREEN}║ Admin: https://${DOMAIN}/admin.html ║${NC}"
|
||||
echo -e "${GREEN}║ App: ${APP_DIR} ║${NC}"
|
||||
echo -e "${GREEN}║ Logs: pm2 logs 3m-portal ║${NC}"
|
||||
echo -e "${GREEN}║ Update: git pull && sudo bash deploy.sh --update ║${NC}"
|
||||
echo -e "${GREEN}║ DB: sqlite3 ${APP_DIR}/data/portal.db ║${NC}"
|
||||
echo -e "${GREEN}║ Update: upload code → sudo bash deploy.sh --update ║${NC}"
|
||||
echo -e "${GREEN}╚══════════════════════════════════════════════════════╝${NC}"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue