Files
leocrm/scripts/fast-deploy.sh
T
Agent Zero 13e9865e8d fix(deploy): fast-deploy.sh frontend uses appuser + docker exec -u root
Container runs as appuser (uid=1000), not app. docker cp copies as root,
so tar extract + chown must run as root via docker exec -u root.
2026-08-21 02:10:07 +02:00

128 lines
4.9 KiB
Bash

#!/usr/bin/env bash
# Fast deploy for LeoCRM.
# Usage:
# bash scripts/fast-deploy.sh frontend # Frontend-only: build + copy (~20s)
# bash scripts/fast-deploy.sh full # Full: Coolify rebuild (~2min)
# Default: frontend
#
# Environment variables:
# COOLIFY_API_TOKEN — Coolify API token (required for full deploy)
# COOLIFY_BASE_URL — Coolify base URL (default: https://server.media-on.de)
# COOLIFY_APP_UUID — Application UUID (optional, resolved via API if absent)
# APP_NAME — Application name for API lookup (default: leocrm-api)
# APP_DOMAIN — App domain (required for full deploy, e.g. https://crm.media-on.de)
# SSH_KEY — SSH key path (default: /a0/usr/workdir/.ssh/coolify-01-root)
# SERVER_IP — Server IP (default: 46.225.91.159)
set -euo pipefail
SSH_KEY="${SSH_KEY:-/a0/usr/workdir/.ssh/coolify-01-root}"
SERVER_IP="${SERVER_IP:-46.225.91.159}"
SERVER="root@${SERVER_IP}"
SSH_OPTS="-o StrictHostKeyChecking=no -i $SSH_KEY"
MODE="${1:-frontend}"
# Resolve repo root from script location
cd "$(dirname "$0")/.."
REPO_ROOT="$(pwd)"
# ─── Helper: Resolve app UUID via Coolify API ────────────────────────
resolve_app_uuid() {
local token="${COOLIFY_API_TOKEN:-}"
local base_url="${COOLIFY_BASE_URL:-https://server.media-on.de}"
local app_name="${APP_NAME:-}"
if [ -z "$app_name" ] && [ -n "${APP_DOMAIN:-}" ]; then
app_name="$(echo "$APP_DOMAIN" | sed 's|.*://||' | sed 's|\..*||')"
fi
app_name="${app_name:-app}"
if [ -z "$token" ]; then
echo "ERROR: COOLIFY_API_TOKEN not set" >&2
return 1
fi
curl -sS -H "Authorization: Bearer $token" \
"${base_url}/api/v1/applications" \
| python3 -c "
import sys, json
apps = json.load(sys.stdin)
for app in apps:
if app.get('name') == '${app_name}':
print(app.get('uuid', ''))
break
" 2>/dev/null
}
# ─── Full Deploy ─────────────────────────────────────────────────────
if [ "$MODE" = "full" ]; then
echo "[Full Deploy] Triggering Coolify rebuild..."
if [ -z "${COOLIFY_API_TOKEN:-}" ]; then
echo "ERROR: COOLIFY_API_TOKEN not set" >&2
exit 1
fi
if [ -z "${APP_DOMAIN:-}" ]; then
echo "ERROR: APP_DOMAIN not set (e.g. https://crm.media-on.de)" >&2
exit 1
fi
COOLIFY_API_TOKEN="$COOLIFY_API_TOKEN" \
COOLIFY_BASE_URL="${COOLIFY_BASE_URL:-https://server.media-on.de}" \
COOLIFY_APP_UUID="${COOLIFY_APP_UUID:-}" \
COOLIFY_WORKER_UUID="${COOLIFY_WORKER_UUID:-}" \
APP_NAME="${APP_NAME:-leocrm-api}" \
WORKER_NAME="${WORKER_NAME:-leocrm-worker}" \
APP_DOMAIN="$APP_DOMAIN" \
SSH_KEY="$SSH_KEY" \
SERVER_IP="$SERVER_IP" \
/opt/venv/bin/python "$REPO_ROOT/scripts/deploy.py"
exit 0
fi
# ─── Frontend-only Fast Deploy ──────────────────────────────────────
# Resolve app UUID
APP_UUID="${COOLIFY_APP_UUID:-}"
if [ -z "$APP_UUID" ]; then
if [ -z "${COOLIFY_API_TOKEN:-}" ]; then
echo "ERROR: COOLIFY_APP_UUID or COOLIFY_API_TOKEN must be set" >&2
exit 1
fi
echo "[1/6] Resolving app UUID via Coolify API..."
APP_UUID="$(resolve_app_uuid)"
if [ -z "$APP_UUID" ]; then
echo "ERROR: Could not resolve app UUID" >&2
exit 1
fi
echo " App UUID: $APP_UUID"
fi
echo "[1/5] Building frontend..."
cd "$REPO_ROOT/frontend"
npm run build 2>&1 | tail -3
echo "[2/5] Finding container..."
# Coolify containers are named like <service>-<uuid>-<timestamp> (e.g. crm_app-<uuid>-<ts>).
# Try legacy UUID-prefix first, then fall back to any running container that contains the UUID
# and has 'app' in its name (covers crm_app-<uuid>-<ts> naming convention).
CONTAINER=$(ssh $SSH_OPTS $SERVER "docker ps --format '{{.Names}}' | grep '^${APP_UUID}-' | head -1")
if [ -z "$CONTAINER" ]; then
CONTAINER=$(ssh $SSH_OPTS $SERVER "docker ps --format '{{.Names}}' | grep '${APP_UUID}' | grep 'app' | head -1")
fi
if [ -z "$CONTAINER" ]; then
echo "ERROR: Could not find app container containing UUID ${APP_UUID}" >&2
exit 1
fi
echo " Container: $CONTAINER"
echo "[3/5] Packaging & uploading..."
tar czf /tmp/frontend-dist.tar.gz -C dist .
scp $SSH_OPTS /tmp/frontend-dist.tar.gz $SERVER:/tmp/frontend-dist.tar.gz
echo "[4/5] Copying into container..."
ssh $SSH_OPTS $SERVER "docker cp /tmp/frontend-dist.tar.gz $CONTAINER:/tmp/ && docker exec -u root $CONTAINER sh -c 'cd /app/frontend/dist && rm -f assets/*.js assets/*.css assets/*.map sw.js registerSW.js workbox-*.js && tar xzf /tmp/frontend-dist.tar.gz && chown -R appuser:appuser /app/frontend/dist && rm -f /tmp/frontend-dist.tar.gz' && rm -f /tmp/frontend-dist.tar.gz"
echo "[5/5] Done! Frontend deployed in ~20s."
echo " No restart needed — static files served directly."
echo " Browser: Strg+Shift+R for hard reload."