149 lines
3.6 KiB
Bash
Executable File
149 lines
3.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
|
|
APP_DIR="${APP_DIR:-/www/wwwroot/wx_service}"
|
|
DIST_DIR="${DIST_DIR:-${APP_DIR}/dist}"
|
|
BIN_PATH="${BIN_PATH:-${DIST_DIR}/wx_service}"
|
|
SOURCE_BIN="${SOURCE_BIN:-}"
|
|
SERVICE_NAME="${SERVICE_NAME:-wx_service}"
|
|
PORT="${PORT:-8080}"
|
|
HEALTH_URL="${HEALTH_URL:-http://127.0.0.1:${PORT}/healthz}"
|
|
RUN_USER="${RUN_USER:-www}"
|
|
RUN_GROUP="${RUN_GROUP:-www}"
|
|
RELEASE_ID="${RELEASE_ID:-manual-$(date +%Y%m%d%H%M%S)}"
|
|
KEEP_BACKUPS="${KEEP_BACKUPS:-5}"
|
|
SYNC_CODE="${SYNC_CODE:-false}"
|
|
DEPLOY_REF="${DEPLOY_REF:-main}"
|
|
INSTALL_SERVICE="${INSTALL_SERVICE:-true}"
|
|
|
|
log() {
|
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
|
|
}
|
|
|
|
health_check() {
|
|
local tries=30
|
|
while [ "$tries" -gt 0 ]; do
|
|
if command -v curl >/dev/null 2>&1; then
|
|
if curl -fsS "$HEALTH_URL" >/dev/null; then
|
|
return 0
|
|
fi
|
|
else
|
|
if wget -q -O - "$HEALTH_URL" >/dev/null; then
|
|
return 0
|
|
fi
|
|
fi
|
|
tries=$((tries - 1))
|
|
sleep 2
|
|
done
|
|
return 1
|
|
}
|
|
|
|
restart_service() {
|
|
if command -v systemctl >/dev/null 2>&1 && systemctl list-unit-files | grep -q "^${SERVICE_NAME}.service"; then
|
|
log "restarting systemd service: ${SERVICE_NAME}"
|
|
systemctl restart "$SERVICE_NAME"
|
|
else
|
|
log "systemd service not found, fallback to pkill + nohup"
|
|
pkill -f "$BIN_PATH" || true
|
|
su -s /bin/bash - "$RUN_USER" -c "cd '$DIST_DIR' && nohup '$BIN_PATH' >> /www/wwwlogs/${SERVICE_NAME}.stdout.log 2>&1 &"
|
|
fi
|
|
}
|
|
|
|
create_service_if_needed() {
|
|
if [ "$INSTALL_SERVICE" != "true" ]; then
|
|
return 0
|
|
fi
|
|
|
|
if ! command -v systemctl >/dev/null 2>&1; then
|
|
return 0
|
|
fi
|
|
|
|
if systemctl list-unit-files | grep -q "^${SERVICE_NAME}.service"; then
|
|
return 0
|
|
fi
|
|
|
|
log "creating systemd service: ${SERVICE_NAME}"
|
|
cat > "/etc/systemd/system/${SERVICE_NAME}.service" <<SERVICE
|
|
[Unit]
|
|
Description=wx_service API
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=${RUN_USER}
|
|
Group=${RUN_GROUP}
|
|
WorkingDirectory=${DIST_DIR}
|
|
ExecStart=${BIN_PATH}
|
|
Restart=always
|
|
RestartSec=3
|
|
LimitNOFILE=65535
|
|
Environment=GIN_MODE=release
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
SERVICE
|
|
|
|
systemctl daemon-reload
|
|
systemctl enable "$SERVICE_NAME"
|
|
}
|
|
|
|
if [ -z "$SOURCE_BIN" ]; then
|
|
echo "SOURCE_BIN is required" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f "$SOURCE_BIN" ]; then
|
|
echo "binary not found: $SOURCE_BIN" >&2
|
|
exit 1
|
|
fi
|
|
|
|
log "deploy start, release: ${RELEASE_ID}"
|
|
mkdir -p "$DIST_DIR" "$APP_DIR/backups"
|
|
|
|
if [ "$SYNC_CODE" = "true" ] && [ -d "$APP_DIR/.git" ]; then
|
|
log "syncing code from github ref: ${DEPLOY_REF}"
|
|
git -C "$APP_DIR" fetch --all --prune
|
|
git -C "$APP_DIR" reset --hard "$DEPLOY_REF"
|
|
fi
|
|
|
|
backup_path=""
|
|
if [ -f "$BIN_PATH" ]; then
|
|
backup_path="$APP_DIR/backups/wx_service.${RELEASE_ID}.bak"
|
|
cp -f "$BIN_PATH" "$backup_path"
|
|
log "backup created: $backup_path"
|
|
fi
|
|
|
|
install -m 755 "$SOURCE_BIN" "${BIN_PATH}.new"
|
|
mv -f "${BIN_PATH}.new" "$BIN_PATH"
|
|
chown "$RUN_USER:$RUN_GROUP" "$BIN_PATH" || true
|
|
|
|
if [ ! -f "$DIST_DIR/.env" ] && [ -f "$APP_DIR/.env" ]; then
|
|
cp -f "$APP_DIR/.env" "$DIST_DIR/.env"
|
|
chown "$RUN_USER:$RUN_GROUP" "$DIST_DIR/.env" || true
|
|
fi
|
|
|
|
create_service_if_needed
|
|
restart_service
|
|
|
|
if health_check; then
|
|
log "health check success: $HEALTH_URL"
|
|
else
|
|
log "health check failed, rollback"
|
|
if [ -n "$backup_path" ] && [ -f "$backup_path" ]; then
|
|
cp -f "$backup_path" "$BIN_PATH"
|
|
chown "$RUN_USER:$RUN_GROUP" "$BIN_PATH" || true
|
|
restart_service || true
|
|
fi
|
|
exit 1
|
|
fi
|
|
|
|
if [ -f "$SOURCE_BIN" ] && [[ "$SOURCE_BIN" == /tmp/* ]]; then
|
|
rm -f "$SOURCE_BIN"
|
|
fi
|
|
|
|
if [ -d "$APP_DIR/backups" ]; then
|
|
ls -1t "$APP_DIR"/backups/wx_service.*.bak 2>/dev/null | tail -n +$((KEEP_BACKUPS + 1)) | xargs -r rm -f
|
|
fi
|
|
|
|
log "deploy done"
|