scholarr/.env.example

159 lines
5.3 KiB
Text

# ------------------------------
# Compose + Database
# ------------------------------
POSTGRES_DB=scholar
POSTGRES_USER=scholar
POSTGRES_PASSWORD=change-me
DATABASE_URL=postgresql+asyncpg://scholar:scholar@db:5432/scholar
# Optional override. If empty, tests derive "<DATABASE_URL db name>_test".
TEST_DATABASE_URL=
SCHOLARR_IMAGE=justinzeus/scholarr:latest
# ------------------------------
# App Runtime + Networking
# ------------------------------
APP_NAME=scholarr
APP_HOST=0.0.0.0
APP_PORT=8000
APP_HOST_PORT=8000
APP_RELOAD=0
MIGRATE_ON_START=1
FRONTEND_ENABLED=1
FRONTEND_DIST_DIR=/app/frontend/dist
# ------------------------------
# Database Pool
# ------------------------------
DATABASE_POOL_MODE=auto
DATABASE_POOL_SIZE=5
DATABASE_POOL_MAX_OVERFLOW=10
DATABASE_POOL_TIMEOUT_SECONDS=30
# ------------------------------
# Frontend Dev Overrides
# ------------------------------
FRONTEND_HOST_PORT=5173
CHOKIDAR_USEPOLLING=1
VITE_DEV_API_PROXY_TARGET=http://app:8000
# ------------------------------
# Auth + Session
# ------------------------------
SESSION_SECRET_KEY=replace-with-a-long-random-secret-at-least-32-characters
SESSION_COOKIE_SECURE=1
LOGIN_RATE_LIMIT_ATTEMPTS=5
LOGIN_RATE_LIMIT_WINDOW_SECONDS=60
# ------------------------------
# HTTP Security Headers + CSP
# ------------------------------
SECURITY_HEADERS_ENABLED=1
SECURITY_X_CONTENT_TYPE_OPTIONS=nosniff
SECURITY_X_FRAME_OPTIONS=DENY
SECURITY_REFERRER_POLICY=strict-origin-when-cross-origin
SECURITY_PERMISSIONS_POLICY=accelerometer=(), autoplay=(), camera=(), display-capture=(), geolocation=(), gyroscope=(), microphone=(), payment=(), usb=()
SECURITY_CROSS_ORIGIN_OPENER_POLICY=same-origin
SECURITY_CROSS_ORIGIN_RESOURCE_POLICY=same-origin
SECURITY_CSP_ENABLED=1
SECURITY_CSP_POLICY=default-src 'self'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; img-src 'self' data: https:; script-src 'self'; style-src 'self' 'unsafe-inline'; font-src 'self' data:; connect-src 'self'; object-src 'none'
SECURITY_CSP_DOCS_POLICY=default-src 'self'; img-src 'self' data: https:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; font-src 'self' data:; connect-src 'self' https:; object-src 'none'; frame-ancestors 'none'
SECURITY_CSP_REPORT_ONLY=0
SECURITY_STRICT_TRANSPORT_SECURITY_ENABLED=0
SECURITY_STRICT_TRANSPORT_SECURITY_MAX_AGE=31536000
SECURITY_STRICT_TRANSPORT_SECURITY_INCLUDE_SUBDOMAINS=1
SECURITY_STRICT_TRANSPORT_SECURITY_PRELOAD=0
# ------------------------------
# Logging
# ------------------------------
LOG_LEVEL=INFO
LOG_FORMAT=console
LOG_REQUESTS=1
LOG_UVICORN_ACCESS=0
LOG_REQUEST_SKIP_PATHS=/healthz
LOG_REDACT_FIELDS=
# ------------------------------
# Scheduler + Ingestion Safety
# ------------------------------
SCHEDULER_ENABLED=1
SCHEDULER_TICK_SECONDS=60
SCHEDULER_QUEUE_BATCH_SIZE=10
SCHEDULER_PDF_QUEUE_BATCH_SIZE=15
INGESTION_AUTOMATION_ALLOWED=1
INGESTION_MANUAL_RUN_ALLOWED=1
INGESTION_MIN_RUN_INTERVAL_MINUTES=15
INGESTION_MIN_REQUEST_DELAY_SECONDS=2
INGESTION_NETWORK_ERROR_RETRIES=1
INGESTION_RETRY_BACKOFF_SECONDS=1.0
INGESTION_RATE_LIMIT_RETRIES=3
INGESTION_RATE_LIMIT_BACKOFF_SECONDS=30.0
INGESTION_MAX_PAGES_PER_SCHOLAR=30
INGESTION_PAGE_SIZE=100
INGESTION_ALERT_BLOCKED_FAILURE_THRESHOLD=1
INGESTION_ALERT_NETWORK_FAILURE_THRESHOLD=2
INGESTION_ALERT_RETRY_SCHEDULED_THRESHOLD=3
INGESTION_SAFETY_COOLDOWN_BLOCKED_SECONDS=1800
INGESTION_SAFETY_COOLDOWN_NETWORK_SECONDS=900
INGESTION_CONTINUATION_QUEUE_ENABLED=1
INGESTION_CONTINUATION_BASE_DELAY_SECONDS=120
INGESTION_CONTINUATION_MAX_DELAY_SECONDS=3600
INGESTION_CONTINUATION_MAX_ATTEMPTS=6
# ------------------------------
# Scholar Images + Name Search Safety
# ------------------------------
SCHOLAR_IMAGE_UPLOAD_DIR=/var/lib/scholarr/uploads
SCHOLAR_IMAGE_UPLOAD_MAX_BYTES=2000000
SCHOLAR_NAME_SEARCH_ENABLED=1
SCHOLAR_NAME_SEARCH_CACHE_TTL_SECONDS=21600
SCHOLAR_NAME_SEARCH_BLOCKED_CACHE_TTL_SECONDS=300
SCHOLAR_NAME_SEARCH_CACHE_MAX_ENTRIES=512
SCHOLAR_NAME_SEARCH_MIN_INTERVAL_SECONDS=8.0
SCHOLAR_NAME_SEARCH_INTERVAL_JITTER_SECONDS=2.0
SCHOLAR_NAME_SEARCH_COOLDOWN_BLOCK_THRESHOLD=1
SCHOLAR_NAME_SEARCH_COOLDOWN_SECONDS=1800
SCHOLAR_NAME_SEARCH_ALERT_RETRY_COUNT_THRESHOLD=2
SCHOLAR_NAME_SEARCH_ALERT_COOLDOWN_REJECTIONS_THRESHOLD=3
# ------------------------------
# OA Enrichment + PDF Resolution
# ------------------------------
UNPAYWALL_ENABLED=1
UNPAYWALL_EMAIL=
UNPAYWALL_TIMEOUT_SECONDS=4.0
UNPAYWALL_MIN_INTERVAL_SECONDS=0.6
UNPAYWALL_MAX_ITEMS_PER_REQUEST=20
UNPAYWALL_RETRY_COOLDOWN_SECONDS=1800
UNPAYWALL_PDF_DISCOVERY_ENABLED=1
UNPAYWALL_PDF_DISCOVERY_MAX_CANDIDATES=5
UNPAYWALL_PDF_DISCOVERY_MAX_HTML_BYTES=500000
ARXIV_ENABLED=1
ARXIV_TIMEOUT_SECONDS=3.0
ARXIV_MIN_INTERVAL_SECONDS=4.0
ARXIV_RATE_LIMIT_COOLDOWN_SECONDS=60.0
ARXIV_DEFAULT_MAX_RESULTS=3
ARXIV_CACHE_TTL_SECONDS=900
ARXIV_CACHE_MAX_ENTRIES=512
ARXIV_MAILTO=
PDF_AUTO_RETRY_INTERVAL_SECONDS=86400
PDF_AUTO_RETRY_FIRST_INTERVAL_SECONDS=3600
PDF_AUTO_RETRY_MAX_ATTEMPTS=3
CROSSREF_ENABLED=1
CROSSREF_MAX_ROWS=10
CROSSREF_TIMEOUT_SECONDS=8.0
CROSSREF_MIN_INTERVAL_SECONDS=0.6
CROSSREF_MAX_LOOKUPS_PER_REQUEST=8
OPENALEX_API_KEY=
CROSSREF_API_TOKEN=
CROSSREF_API_MAILTO=
# ------------------------------
# Startup Bootstrap + DB Wait
# ------------------------------
BOOTSTRAP_ADMIN_ON_START=0
BOOTSTRAP_ADMIN_EMAIL=
BOOTSTRAP_ADMIN_PASSWORD=
BOOTSTRAP_ADMIN_FORCE_PASSWORD=0
DB_WAIT_TIMEOUT_SECONDS=60
DB_WAIT_INTERVAL_SECONDS=2