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
This commit is contained in:
88
deploy.sh
88
deploy.sh
@@ -10,6 +10,7 @@ set -u # Exit on undefined variable
|
|||||||
APP_NAME="llm-proxy"
|
APP_NAME="llm-proxy"
|
||||||
APP_USER="llmproxy"
|
APP_USER="llmproxy"
|
||||||
APP_GROUP="llmproxy"
|
APP_GROUP="llmproxy"
|
||||||
|
GIT_REPO="ssh://git.dustin.coffee:2222/hobokenchicken/llm-proxy.git"
|
||||||
INSTALL_DIR="/opt/$APP_NAME"
|
INSTALL_DIR="/opt/$APP_NAME"
|
||||||
CONFIG_DIR="/etc/$APP_NAME"
|
CONFIG_DIR="/etc/$APP_NAME"
|
||||||
DATA_DIR="/var/lib/$APP_NAME"
|
DATA_DIR="/var/lib/$APP_NAME"
|
||||||
@@ -111,7 +112,9 @@ setup_directories() {
|
|||||||
|
|
||||||
# Create user and group if they don't exist
|
# Create user and group if they don't exist
|
||||||
if ! id "$APP_USER" &>/dev/null; then
|
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
|
fi
|
||||||
|
|
||||||
# Create directories
|
# Create directories
|
||||||
@@ -139,7 +142,7 @@ build_application() {
|
|||||||
# Clone or update repository
|
# Clone or update repository
|
||||||
if [[ ! -d "$INSTALL_DIR/.git" ]]; then
|
if [[ ! -d "$INSTALL_DIR/.git" ]]; then
|
||||||
log_info "Cloning repository..."
|
log_info "Cloning repository..."
|
||||||
git clone https://github.com/yourusername/llm-proxy.git "$INSTALL_DIR"
|
git clone "$GIT_REPO" "$INSTALL_DIR"
|
||||||
else
|
else
|
||||||
log_info "Updating repository..."
|
log_info "Updating repository..."
|
||||||
cd "$INSTALL_DIR"
|
cd "$INSTALL_DIR"
|
||||||
@@ -249,7 +252,7 @@ create_systemd_service() {
|
|||||||
cat > "$SERVICE_FILE" << EOF
|
cat > "$SERVICE_FILE" << EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=LLM Proxy Gateway
|
Description=LLM Proxy Gateway
|
||||||
Documentation=https://github.com/yourusername/llm-proxy
|
Documentation=https://git.dustin.coffee/hobokenchicken/llm-proxy
|
||||||
After=network.target
|
After=network.target
|
||||||
Wants=network.target
|
Wants=network.target
|
||||||
|
|
||||||
@@ -483,7 +486,7 @@ ${YELLOW}Configuration files:${NC}
|
|||||||
Logs: $LOG_DIR/
|
Logs: $LOG_DIR/
|
||||||
|
|
||||||
${GREEN}For more information, see:${NC}
|
${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/README.md
|
||||||
$INSTALL_DIR/deployment.md
|
$INSTALL_DIR/deployment.md
|
||||||
|
|
||||||
@@ -519,21 +522,37 @@ update() {
|
|||||||
|
|
||||||
check_root
|
check_root
|
||||||
|
|
||||||
# Stop service
|
# Pull latest changes (while service keeps running)
|
||||||
systemctl stop "$APP_NAME"
|
|
||||||
|
|
||||||
# Update from git
|
|
||||||
cd "$INSTALL_DIR"
|
cd "$INSTALL_DIR"
|
||||||
|
log_info "Pulling latest changes..."
|
||||||
git pull
|
git pull
|
||||||
|
|
||||||
# Rebuild
|
# Build new binary (service stays up on the old binary)
|
||||||
cargo build --release
|
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
|
# Verify binary exists
|
||||||
systemctl start "$APP_NAME"
|
if [[ ! -f "target/release/$APP_NAME" ]]; then
|
||||||
|
log_error "Binary not found after build — aborting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
log_info "Update completed successfully!"
|
# Restart service to pick up new binary
|
||||||
systemctl status "$APP_NAME" --no-pager
|
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
|
# Uninstall function
|
||||||
@@ -577,18 +596,49 @@ Usage: $0 [command]
|
|||||||
|
|
||||||
Commands:
|
Commands:
|
||||||
deploy - Install and configure LLM Proxy Gateway
|
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
|
uninstall - Remove LLM Proxy Gateway
|
||||||
help - Show this help message
|
help - Show this help message
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
$0 deploy # Full installation
|
$0 deploy # Full installation
|
||||||
$0 update # Update to latest version
|
$0 update # Update to latest version
|
||||||
$0 uninstall # Remove installation
|
$0 status # Check if service is healthy
|
||||||
|
$0 logs # Follow live logs
|
||||||
|
|
||||||
EOF
|
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
|
# Parse command line arguments
|
||||||
case "${1:-}" in
|
case "${1:-}" in
|
||||||
deploy)
|
deploy)
|
||||||
@@ -597,6 +647,12 @@ case "${1:-}" in
|
|||||||
update)
|
update)
|
||||||
update
|
update
|
||||||
;;
|
;;
|
||||||
|
status)
|
||||||
|
status
|
||||||
|
;;
|
||||||
|
logs)
|
||||||
|
logs
|
||||||
|
;;
|
||||||
uninstall)
|
uninstall)
|
||||||
uninstall
|
uninstall
|
||||||
;;
|
;;
|
||||||
|
|||||||
Reference in New Issue
Block a user