Files
geointel/deploy/unraid/all-in-one-start.sh
T
Codex 5699006a5e
GeoIntel CI / docs-smoke (push) Canceled after 0s
GeoIntel CI / contract-smoke (push) Canceled after 0s
Harden immutable release deployment
2026-07-18 02:31:28 +02:00

104 lines
3.5 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
export POSTGRES_DB="${GEOINTEL_POSTGRES_DB:-${POSTGRES_DB:-geointel}}"
export POSTGRES_USER="${GEOINTEL_POSTGRES_USER:-${POSTGRES_USER:-geointel}}"
export POSTGRES_PASSWORD="${GEOINTEL_POSTGRES_PASSWORD:-${POSTGRES_PASSWORD:-geointel}}"
export PGDATA="${PGDATA:-/var/lib/postgresql/data}"
export STORAGE_ROOT="${STORAGE_ROOT:-${GEOINTEL_STORAGE_ROOT:-/app/storage}}"
export DATABASE_URL="${DATABASE_URL:-postgresql+psycopg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@127.0.0.1:5432/${POSTGRES_DB}}"
export CORS_ORIGINS="${GEOINTEL_CORS_ORIGINS:-${CORS_ORIGINS:-http://localhost:1202,http://127.0.0.1:1202}}"
export MAX_UPLOAD_MB="${GEOINTEL_MAX_UPLOAD_MB:-${MAX_UPLOAD_MB:-500}}"
export YOLO_MODELS_DIR="${YOLO_MODELS_DIR:-/app/models}"
export YOLO_CONFIG_DIR="${YOLO_CONFIG_DIR:-$STORAGE_ROOT/ultralytics}"
export GEOINTEL_RECONCILE_INTERRUPTED_RUNS_ON_STARTUP="${GEOINTEL_RECONCILE_INTERRUPTED_RUNS_ON_STARTUP:-true}"
case "$MAX_UPLOAD_MB" in
''|*[!0-9]*)
echo "GEOINTEL_MAX_UPLOAD_MB must be a whole number between 1 and 2048." >&2
exit 2
;;
esac
if [ "$MAX_UPLOAD_MB" -lt 1 ] || [ "$MAX_UPLOAD_MB" -gt 2048 ]; then
echo "GEOINTEL_MAX_UPLOAD_MB must be between 1 and 2048." >&2
exit 2
fi
case "${GEOINTEL_ENV:-production}:${POSTGRES_PASSWORD}" in
production:|production:geointel|production:postgres|production:password|production:changeme|production:change-me-before-shared-use)
echo "Refusing to start production with an empty or known-default PostGIS password." >&2
exit 2
;;
esac
sed -i "s/__GEOINTEL_MAX_UPLOAD_MB__/${MAX_UPLOAD_MB}/g" /etc/nginx/conf.d/default.conf
nginx -t
mkdir -p "$PGDATA" "$STORAGE_ROOT" "$YOLO_CONFIG_DIR" /run/nginx /var/log/nginx
chown -R postgres:postgres "$PGDATA"
postgres_pid=""
backend_pid=""
shutdown() {
if [ -n "$backend_pid" ] && kill -0 "$backend_pid" 2>/dev/null; then
kill "$backend_pid" 2>/dev/null || true
fi
if [ -n "$postgres_pid" ] && kill -0 "$postgres_pid" 2>/dev/null; then
kill "$postgres_pid" 2>/dev/null || true
wait "$postgres_pid" 2>/dev/null || true
fi
}
trap shutdown INT TERM EXIT
echo "Starting embedded PostGIS..."
/usr/local/bin/docker-entrypoint.sh postgres &
postgres_pid="$!"
echo "Waiting for embedded PostGIS..."
for attempt in $(seq 1 60); do
if pg_isready -h 127.0.0.1 -U "$POSTGRES_USER" -d "$POSTGRES_DB" >/dev/null 2>&1; then
echo "PostGIS is ready after attempt ${attempt}."
break
fi
if ! kill -0 "$postgres_pid" 2>/dev/null; then
echo "PostGIS process exited before becoming ready."
wait "$postgres_pid"
fi
sleep 2
done
if ! pg_isready -h 127.0.0.1 -U "$POSTGRES_USER" -d "$POSTGRES_DB" >/dev/null 2>&1; then
echo "PostGIS did not become ready."
exit 1
fi
echo "Applying Alembic migrations..."
python -m alembic upgrade head
echo "Starting GeoIntel backend..."
uvicorn app.main:app --host 127.0.0.1 --port 8000 &
backend_pid="$!"
echo "Waiting for GeoIntel backend..."
python - <<'PY'
import time
import urllib.request
last_error = None
for attempt in range(1, 61):
try:
urllib.request.urlopen("http://127.0.0.1:8000/health/ready", timeout=3).read()
print(f"Backend is ready after attempt {attempt}.")
break
except Exception as exc:
last_error = exc
print(f"Backend not ready yet ({attempt}/60): {exc}")
time.sleep(1)
else:
raise SystemExit(f"Backend did not become ready: {last_error}")
PY
echo "Starting nginx frontend on container port 80..."
exec nginx -g "daemon off;"