abgeordnetenwatch PWA + backend
feature-based React PWA with Hono backend: - feed from abgeordnetenwatch.de API (polls by topic + politician) - follow topics, search and follow politicians - geo-based politician discovery via Nominatim - push notifications for new polls via web-push - service worker with offline caching - deploy to Uberspace 8 (systemd, PostgreSQL, web backend proxy) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
84
deploy.sh
Executable file
84
deploy.sh
Executable file
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env bash
|
||||
# deploy.sh — build and deploy PWA + backend to Uberspace 8
|
||||
# Usage: ./deploy.sh [uberspace-user@host] (default: serve)
|
||||
set -euo pipefail
|
||||
|
||||
REMOTE="${1:-serve}"
|
||||
LOCAL_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
# reuse a single SSH connection to avoid rate limiting
|
||||
SSH_SOCK="/tmp/deploy-ssh-$$"
|
||||
ssh -fNM -o ControlMaster=yes -S "$SSH_SOCK" "$REMOTE"
|
||||
trap 'ssh -S "$SSH_SOCK" -O exit "$REMOTE" 2>/dev/null' EXIT
|
||||
r() { ssh -S "$SSH_SOCK" "$REMOTE" "$@"; }
|
||||
|
||||
REMOTE_USER=$(r 'echo $USER')
|
||||
REMOTE_AGW_DIR="/var/www/virtual/$REMOTE_USER/html/agw"
|
||||
REMOTE_SERVICE_DIR="/home/$REMOTE_USER/services/agw-backend"
|
||||
SERVICE_NAME="agw-backend"
|
||||
BACKEND_PORT=3002
|
||||
|
||||
# --- PWA ---
|
||||
|
||||
echo "==> Building PWA"
|
||||
cd "$LOCAL_DIR"
|
||||
bun install --frozen-lockfile
|
||||
bun run build
|
||||
|
||||
echo "==> Deploying static files to $REMOTE:$REMOTE_AGW_DIR"
|
||||
r "mkdir -p $REMOTE_AGW_DIR"
|
||||
rsync -avz --delete -e "ssh -S $SSH_SOCK" \
|
||||
"$LOCAL_DIR/dist/" "$REMOTE:$REMOTE_AGW_DIR/"
|
||||
|
||||
# --- Backend ---
|
||||
|
||||
echo "==> Deploying backend to $REMOTE:$REMOTE_SERVICE_DIR"
|
||||
r "mkdir -p $REMOTE_SERVICE_DIR"
|
||||
rsync -avz --delete -e "ssh -S $SSH_SOCK" \
|
||||
--exclude='node_modules/' \
|
||||
--exclude='.env' \
|
||||
"$LOCAL_DIR/server/" "$REMOTE:$REMOTE_SERVICE_DIR/"
|
||||
|
||||
echo "==> Installing backend dependencies"
|
||||
r "cd $REMOTE_SERVICE_DIR && npm install"
|
||||
|
||||
echo "==> Checking .env exists"
|
||||
r "test -f $REMOTE_SERVICE_DIR/.env || { echo 'ERROR: $REMOTE_SERVICE_DIR/.env not found — create it first'; exit 1; }"
|
||||
|
||||
echo "==> Running database migrations"
|
||||
r "cd $REMOTE_SERVICE_DIR && set -a && source .env && set +a && npx drizzle-kit migrate"
|
||||
|
||||
# --- systemd user service (Uberspace 8) ---
|
||||
|
||||
echo "==> Configuring systemd user service"
|
||||
r "mkdir -p ~/.config/systemd/user && cat > ~/.config/systemd/user/$SERVICE_NAME.service << EOF
|
||||
[Unit]
|
||||
Description=Abgeordnetenwatch Backend
|
||||
After=network.target postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=$REMOTE_SERVICE_DIR
|
||||
EnvironmentFile=$REMOTE_SERVICE_DIR/.env
|
||||
ExecStart=$REMOTE_SERVICE_DIR/node_modules/.bin/tsx src/index.ts
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
EOF"
|
||||
|
||||
echo "==> Restarting backend service"
|
||||
r "systemctl --user daemon-reload && systemctl --user enable $SERVICE_NAME && systemctl --user restart $SERVICE_NAME"
|
||||
sleep 2
|
||||
r "systemctl --user status $SERVICE_NAME --no-pager" || true
|
||||
|
||||
# --- Web backend (reverse proxy) ---
|
||||
|
||||
echo "==> Configuring web backend for /agw-api/"
|
||||
r "uberspace web backend add /agw-api PORT $BACKEND_PORT --remove-prefix --force --wait" 2>/dev/null || true
|
||||
|
||||
echo ""
|
||||
echo "Done."
|
||||
echo " PWA: https://$REMOTE_USER.uber.space/agw/"
|
||||
echo " Backend: https://$REMOTE_USER.uber.space/agw-api/"
|
||||
Reference in New Issue
Block a user