#!/usr/bin/env bash # Start the Confluence Research backend (serves the frontend on the same origin). # # scripts/run-backend.sh [deploy/confluence-web.env] # # Loads the env file, checks the runtime image and rootless daemon, then runs a # single Uvicorn worker bound to CONFLUENCE_WEB_BIND_HOST:PORT (loopback by default). set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" ENV_FILE="${1:-$ROOT/deploy/confluence-web.env}" PYTHON="${PYTHON:-$ROOT/.venv/bin/python}" if [[ ! -f "$ENV_FILE" ]]; then echo "env file not found: $ENV_FILE (copy deploy/confluence-web.env.example)" >&2 exit 1 fi set -a # shellcheck disable=SC1090 . "$ENV_FILE" set +a # Resolve a relative frontend directory against the repository root. if [[ -n "${CONFLUENCE_WEB_FRONTEND_DIST_DIR:-}" && "${CONFLUENCE_WEB_FRONTEND_DIST_DIR}" != /* ]]; then export CONFLUENCE_WEB_FRONTEND_DIST_DIR="$ROOT/${CONFLUENCE_WEB_FRONTEND_DIST_DIR#./}" fi if [[ "${CONFLUENCE_WEB_DEV_MODE:-false}" != "true" ]]; then if ! docker info --format '{{json .SecurityOptions}}' 2>/dev/null | grep -q rootless; then echo "rootless Docker daemon is required (docker context use rootless)" >&2 exit 1 fi if ! docker image inspect "${CONFLUENCE_WEB_RUNTIME_IMAGE:?}" >/dev/null 2>&1; then echo "runtime image ${CONFLUENCE_WEB_RUNTIME_IMAGE} not found; run: make build-image" >&2 exit 1 fi fi # Optional TLS termination by Uvicorn (see scripts/make-tls.sh). Both or neither. TLS_ARGS=() if [[ -n "${CONFLUENCE_WEB_TLS_CERT:-}" || -n "${CONFLUENCE_WEB_TLS_KEY:-}" ]]; then if [[ -z "${CONFLUENCE_WEB_TLS_CERT:-}" || -z "${CONFLUENCE_WEB_TLS_KEY:-}" ]]; then echo "CONFLUENCE_WEB_TLS_CERT and CONFLUENCE_WEB_TLS_KEY must be set together" >&2 exit 1 fi # Relative paths resolve against the repository root, like the frontend directory. [[ "$CONFLUENCE_WEB_TLS_CERT" != /* ]] && CONFLUENCE_WEB_TLS_CERT="$ROOT/${CONFLUENCE_WEB_TLS_CERT#./}" [[ "$CONFLUENCE_WEB_TLS_KEY" != /* ]] && CONFLUENCE_WEB_TLS_KEY="$ROOT/${CONFLUENCE_WEB_TLS_KEY#./}" for f in "$CONFLUENCE_WEB_TLS_CERT" "$CONFLUENCE_WEB_TLS_KEY"; do if [[ ! -r "$f" ]]; then echo "TLS file not readable: $f" >&2 exit 1 fi done TLS_ARGS=(--ssl-certfile "$CONFLUENCE_WEB_TLS_CERT" --ssl-keyfile "$CONFLUENCE_WEB_TLS_KEY") fi # Timestamped logging for every logger, not just uvicorn's own (a backend warning would # otherwise reach stderr through logging's fallback handler, without a timestamp). LOG_ARGS=() LOG_CONFIG="${CONFLUENCE_WEB_LOG_CONFIG:-$ROOT/deploy/logging.json}" [[ -r "$LOG_CONFIG" ]] && LOG_ARGS=(--log-config "$LOG_CONFIG") exec "$PYTHON" -m uvicorn backend.app:create_app --factory --workers 1 \ --host "${CONFLUENCE_WEB_BIND_HOST:-127.0.0.1}" --port "${CONFLUENCE_WEB_BIND_PORT:-8000}" \ --no-server-header --timeout-keep-alive 5 --limit-concurrency 32 --app-dir "$ROOT" \ "${LOG_ARGS[@]}" "${TLS_ARGS[@]}"