From d5e326bc65bbb74fe465a9c0d665986594613a30 Mon Sep 17 00:00:00 2001 From: hobokenchicken Date: Tue, 3 Mar 2026 09:44:23 -0500 Subject: [PATCH] fix(deploy): harden deploy.sh for Arch Linux and zero-downtime updates - Add GIT_REPO config variable with actual Gitea remote URL - Auto-detect nologin path for Arch/Debian compatibility - Rewrite update() to build before stopping service (minimizes downtime) - Abort update cleanly if build fails without interrupting service - Fix all placeholder github.com/yourusername URLs - Add status and logs convenience commands --- deploy.sh | 88 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 16 deletions(-) diff --git a/deploy.sh b/deploy.sh index 865d220d..9d71ac3d 100755 --- a/deploy.sh +++ b/deploy.sh @@ -10,6 +10,7 @@ set -u # Exit on undefined variable APP_NAME="llm-proxy" APP_USER="llmproxy" APP_GROUP="llmproxy" +GIT_REPO="ssh://git.dustin.coffee:2222/hobokenchicken/llm-proxy.git" INSTALL_DIR="/opt/$APP_NAME" CONFIG_DIR="/etc/$APP_NAME" DATA_DIR="/var/lib/$APP_NAME" @@ -111,7 +112,9 @@ setup_directories() { # Create user and group if they don't exist if ! id "$APP_USER" &>/dev/null; then - useradd -r -s /usr/sbin/nologin -M "$APP_USER" + # Arch uses /usr/bin/nologin, Debian/Ubuntu use /usr/sbin/nologin + NOLOGIN=$(command -v nologin 2>/dev/null || echo "/usr/bin/nologin") + useradd -r -s "$NOLOGIN" -M "$APP_USER" fi # Create directories @@ -139,7 +142,7 @@ build_application() { # Clone or update repository if [[ ! -d "$INSTALL_DIR/.git" ]]; then log_info "Cloning repository..." - git clone https://github.com/yourusername/llm-proxy.git "$INSTALL_DIR" + git clone "$GIT_REPO" "$INSTALL_DIR" else log_info "Updating repository..." cd "$INSTALL_DIR" @@ -249,7 +252,7 @@ create_systemd_service() { cat > "$SERVICE_FILE" << EOF [Unit] Description=LLM Proxy Gateway -Documentation=https://github.com/yourusername/llm-proxy +Documentation=https://git.dustin.coffee/hobokenchicken/llm-proxy After=network.target Wants=network.target @@ -483,7 +486,7 @@ ${YELLOW}Configuration files:${NC} Logs: $LOG_DIR/ ${GREEN}For more information, see:${NC} - https://github.com/yourusername/llm-proxy + https://git.dustin.coffee/hobokenchicken/llm-proxy $INSTALL_DIR/README.md $INSTALL_DIR/deployment.md @@ -519,21 +522,37 @@ update() { check_root - # Stop service - systemctl stop "$APP_NAME" - - # Update from git + # Pull latest changes (while service keeps running) cd "$INSTALL_DIR" + log_info "Pulling latest changes..." git pull - # Rebuild - cargo build --release + # Build new binary (service stays up on the old binary) + log_info "Building release binary (service still running)..." + if ! cargo build --release; then + log_error "Build failed — service was NOT interrupted. Fix the error and try again." + exit 1 + fi - # Restart service - systemctl start "$APP_NAME" + # Verify binary exists + if [[ ! -f "target/release/$APP_NAME" ]]; then + log_error "Binary not found after build — aborting." + exit 1 + fi - log_info "Update completed successfully!" - systemctl status "$APP_NAME" --no-pager + # Restart service to pick up new binary + log_info "Build succeeded. Restarting service..." + systemctl restart "$APP_NAME" + + sleep 2 + if systemctl is-active --quiet "$APP_NAME"; then + log_info "Update completed successfully!" + systemctl status "$APP_NAME" --no-pager + else + log_error "Service failed to start after update. Check logs:" + journalctl -u "$APP_NAME" -n 20 --no-pager + exit 1 + fi } # Uninstall function @@ -577,18 +596,49 @@ Usage: $0 [command] Commands: deploy - Install and configure LLM Proxy Gateway - update - Update existing installation + update - Pull latest changes, rebuild, and restart + status - Show service status and health check + logs - Tail the service logs (Ctrl+C to stop) uninstall - Remove LLM Proxy Gateway help - Show this help message Examples: $0 deploy # Full installation $0 update # Update to latest version - $0 uninstall # Remove installation + $0 status # Check if service is healthy + $0 logs # Follow live logs EOF } +# Status function +status() { + echo "" + log_info "Service status:" + systemctl status "$APP_NAME" --no-pager 2>/dev/null || log_warn "Service not found" + echo "" + + # Health check + if curl -sf http://localhost:8080/health &>/dev/null; then + log_info "Health check: OK" + else + log_warn "Health check: FAILED (service may not be running or port 8080 not responding)" + fi + + # Show current git commit + if [[ -d "$INSTALL_DIR/.git" ]]; then + echo "" + log_info "Installed version:" + git -C "$INSTALL_DIR" log -1 --format=" %h %s (%cr)" 2>/dev/null + fi +} + +# Logs function +logs() { + log_info "Tailing $APP_NAME logs (Ctrl+C to stop)..." + journalctl -u "$APP_NAME" -f +} + # Parse command line arguments case "${1:-}" in deploy) @@ -597,6 +647,12 @@ case "${1:-}" in update) update ;; + status) + status + ;; + logs) + logs + ;; uninstall) uninstall ;;