Files
projectbrain-Public/scripts/unraid-single-entrypoint.sh

110 lines
3.8 KiB
Bash

#!/usr/bin/env sh
set -eu
API_LOG="/tmp/projectbrain-api.log"
PG_LOG="/tmp/projectbrain-postgres.log"
ANALYSIS_WORKER_LOG="/tmp/projectbrain-analysis-worker.log"
PROJECTBRAIN_DATA_DIR="${PROJECTBRAIN_DATA_DIR:-/var/lib/projectbrain}"
PGDATA="${PROJECTBRAIN_POSTGRES_DATA_DIR:-${PROJECTBRAIN_DATA_DIR}/postgres}"
POSTGRES_DB="${POSTGRES_DB:-projectbrain}"
POSTGRES_USER="${POSTGRES_USER:-projectbrain}"
POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-}"
if [ "${PROJECTBRAIN_USE_EXTERNAL_DATABASE:-false}" != "true" ]; then
: "${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required for embedded PostgreSQL}"
export DATABASE_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@127.0.0.1:5432/${POSTGRES_DB}?schema=public"
else
export DATABASE_URL="${DATABASE_URL:?DATABASE_URL is required when PROJECTBRAIN_USE_EXTERNAL_DATABASE=true}"
fi
mkdir -p "${PGDATA}"
mkdir -p /run/postgresql
chown -R postgres:postgres "${PROJECTBRAIN_DATA_DIR}"
chown postgres:postgres /run/postgresql
if [ ! -s "${PGDATA}/PG_VERSION" ]; then
echo "[ProjectBrain] Initializing embedded PostgreSQL data directory..."
pwfile="/tmp/projectbrain-pgpass"
printf '%s' "${POSTGRES_PASSWORD}" > "${pwfile}"
chown postgres:postgres "${pwfile}"
su postgres -c "initdb -D '${PGDATA}' -U '${POSTGRES_USER}' --pwfile='${pwfile}' --auth-host=md5 --auth-local=trust" >/tmp/projectbrain-initdb.log 2>&1 || {
cat /tmp/projectbrain-initdb.log >&2 || true
exit 1
}
rm -f "${pwfile}"
fi
echo "[ProjectBrain] Starting embedded PostgreSQL..."
su postgres -c "pg_ctl -D '${PGDATA}' -o \"-c listen_addresses='127.0.0.1'\" -w start" > "${PG_LOG}" 2>&1
if ! su postgres -c "psql -U '${POSTGRES_USER}' -d postgres -tAc \"SELECT 1 FROM pg_database WHERE datname='${POSTGRES_DB}'\"" | grep -q 1; then
echo "[ProjectBrain] Creating database ${POSTGRES_DB}..."
su postgres -c "createdb -U '${POSTGRES_USER}' '${POSTGRES_DB}'"
fi
cd /app/backend
echo "[ProjectBrain] Starting API inside single-container runtime..."
NODE_OPTIONS="--max-old-space-size=${PROJECTBRAIN_API_HEAP_MB:-512}" sh scripts/docker-entrypoint.sh > "${API_LOG}" 2>&1 &
API_PID="$!"
ANALYSIS_WORKER_SUPERVISOR_PID=""
NGINX_PID=""
cleanup() {
echo "[ProjectBrain] Stopping runtime..."
if [ -n "${ANALYSIS_WORKER_SUPERVISOR_PID}" ]; then
kill "${ANALYSIS_WORKER_SUPERVISOR_PID}" 2>/dev/null || true
fi
if [ -n "${NGINX_PID}" ]; then
kill "${NGINX_PID}" 2>/dev/null || true
fi
kill "${API_PID}" 2>/dev/null || true
su postgres -c "pg_ctl -D '${PGDATA}' -m fast stop" >/dev/null 2>&1 || true
}
trap cleanup INT TERM
echo "[ProjectBrain] Waiting for API readiness..."
attempt=0
until curl -fsS "http://127.0.0.1:4000/api/system/readiness" >/dev/null 2>&1; do
attempt=$((attempt + 1))
if ! kill -0 "${API_PID}" 2>/dev/null; then
echo "[ProjectBrain] API exited before readiness." >&2
cat "${API_LOG}" >&2 || true
exit 1
fi
if [ "${attempt}" -ge 60 ]; then
echo "[ProjectBrain] API did not become ready in time." >&2
cat "${API_LOG}" >&2 || true
exit 1
fi
sleep 1
done
run_analysis_worker() (
child_pid=""
stop_worker() {
if [ -n "${child_pid}" ]; then
kill "${child_pid}" 2>/dev/null || true
wait "${child_pid}" 2>/dev/null || true
fi
exit 0
}
trap stop_worker INT TERM
while true; do
echo "[ProjectBrain] Starting bounded repository-analysis worker..." >> "${ANALYSIS_WORKER_LOG}"
NODE_OPTIONS="--max-old-space-size=${PROJECTBRAIN_ANALYSIS_WORKER_HEAP_MB:-384}" node dist/workers/analysisWorker.js >> "${ANALYSIS_WORKER_LOG}" 2>&1 &
child_pid="$!"
echo 500 > "/proc/${child_pid}/oom_score_adj" 2>/dev/null || true
wait "${child_pid}" || true
child_pid=""
sleep 5
done
)
run_analysis_worker &
ANALYSIS_WORKER_SUPERVISOR_PID="$!"
echo "[ProjectBrain] API and analysis worker are ready. Starting nginx..."
nginx -g "daemon off;" &
NGINX_PID="$!"
wait "${NGINX_PID}"