113 lines
2.8 KiB
Bash
113 lines
2.8 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
APP_NAME="${APP_NAME:-ai-agent-admin}"
|
|
PROJECT_DIR="${PROJECT_DIR:-/opt/ai-agent-admin/current}"
|
|
BACKEND_DIR="${BACKEND_DIR:-${PROJECT_DIR}/backend-fastapi}"
|
|
WEB_DIST_DIR="${WEB_DIST_DIR:-${PROJECT_DIR}/web/apps/web-ele/dist}"
|
|
WEB_ROOT="${WEB_ROOT:-/var/www/ai-agent-admin}"
|
|
SERVICE_NAME="${SERVICE_NAME:-ai-agent-admin}"
|
|
PYTHON_BIN="${PYTHON_BIN:-python3}"
|
|
ENV_FILE="${ENV_FILE:-${BACKEND_DIR}/env/prod.env}"
|
|
BACKEND_PORT="${BACKEND_PORT:-8001}"
|
|
RUN_MIGRATIONS="${RUN_MIGRATIONS:-1}"
|
|
IMPORT_INIT_DATA="${IMPORT_INIT_DATA:-auto}"
|
|
SEED_MULTICA_AGENTS="${SEED_MULTICA_AGENTS:-1}"
|
|
BUILD_WEB="${BUILD_WEB:-0}"
|
|
|
|
log() {
|
|
printf '[%s] %s\n' "${APP_NAME}" "$*"
|
|
}
|
|
|
|
require_file() {
|
|
if [ ! -f "$1" ]; then
|
|
printf 'Missing required file: %s\n' "$1" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
require_dir() {
|
|
if [ ! -d "$1" ]; then
|
|
printf 'Missing required directory: %s\n' "$1" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
require_dir "${PROJECT_DIR}"
|
|
require_dir "${BACKEND_DIR}"
|
|
require_file "${ENV_FILE}"
|
|
|
|
if [ "${BUILD_WEB}" = "1" ]; then
|
|
log "building web-ele"
|
|
(cd "${PROJECT_DIR}/web" && pnpm --filter @vben/web-ele build)
|
|
fi
|
|
|
|
require_file "${WEB_DIST_DIR}/index.html"
|
|
|
|
log "publishing web dist to ${WEB_ROOT}"
|
|
install -d "${WEB_ROOT}"
|
|
rsync -a --delete "${WEB_DIST_DIR}/" "${WEB_ROOT}/"
|
|
|
|
log "preparing backend venv"
|
|
cd "${BACKEND_DIR}"
|
|
if [ ! -x ".venv/bin/python" ]; then
|
|
"${PYTHON_BIN}" -m venv .venv
|
|
fi
|
|
|
|
# shellcheck source=/dev/null
|
|
. .venv/bin/activate
|
|
python -m pip install --upgrade pip
|
|
python -m pip install -r requirements.txt
|
|
|
|
if [ "${RUN_MIGRATIONS}" = "1" ]; then
|
|
log "running alembic migrations"
|
|
ENV=prod python -m alembic upgrade head
|
|
fi
|
|
|
|
if [ "${IMPORT_INIT_DATA}" = "auto" ]; then
|
|
USER_COUNT="$(
|
|
ENV=prod python - <<'PY'
|
|
import asyncio
|
|
from sqlalchemy import text
|
|
from app.database import AsyncSessionLocal
|
|
|
|
async def main():
|
|
try:
|
|
async with AsyncSessionLocal() as db:
|
|
result = await db.execute(text("SELECT COUNT(*) FROM core_user"))
|
|
print(result.scalar() or 0)
|
|
except Exception:
|
|
print(0)
|
|
|
|
asyncio.run(main())
|
|
PY
|
|
)"
|
|
if [ "${USER_COUNT}" = "0" ] && [ -f "db_init.json" ]; then
|
|
log "importing initial data"
|
|
ENV=prod python scripts/loaddata.py db_init.json
|
|
fi
|
|
fi
|
|
|
|
if [ "${SEED_MULTICA_AGENTS}" = "1" ] && [ -f "scripts/seed_multica_org_agents.py" ]; then
|
|
log "seeding Multica organization agents"
|
|
ENV=prod python scripts/seed_multica_org_agents.py --apply
|
|
fi
|
|
|
|
log "restarting ${SERVICE_NAME}"
|
|
if command -v systemctl >/dev/null 2>&1; then
|
|
systemctl daemon-reload
|
|
systemctl restart "${SERVICE_NAME}"
|
|
fi
|
|
|
|
if command -v nginx >/dev/null 2>&1; then
|
|
log "reloading nginx"
|
|
nginx -t
|
|
if command -v systemctl >/dev/null 2>&1; then
|
|
systemctl reload nginx
|
|
else
|
|
nginx -s reload
|
|
fi
|
|
fi
|
|
|
|
log "done: backend port ${BACKEND_PORT}, web root ${WEB_ROOT}"
|