lazyflat/web/settings.py
EiSiMo 6eada58629 fix(web): take git SHA from Coolify's runtime SOURCE_COMMIT
The .git-COPY approach from a35e6c9 never actually deployed: BuildKit
rejected `COPY .git /tmp/.git` with "failed to calculate checks"
because Coolify's build context doesn't include .git, so deploy 86
failed and the stale 0144cb2 image kept serving "build dev" in the
footer.

Coolify v4 already injects SOURCE_COMMIT into the container env at
runtime by default (build-time only on opt-in, since it busts the
build cache by definition). Map SOURCE_COMMIT → GIT_COMMIT in
docker-compose, drop the build-time SHA stamping (and the repo-root
build context that only existed to reach .git), and shrink
_read_git_commit to a one-liner getenv.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 11:04:24 +02:00

67 lines
3 KiB
Python

import secrets
import sys
from os import getenv
from pathlib import Path
from dotenv import load_dotenv
load_dotenv()
def _required(key: str) -> str:
val = getenv(key)
if not val:
print(f"missing required env var: {key}", file=sys.stderr)
sys.exit(1)
return val
# --- Admin bootstrap ----------------------------------------------------------
# On first boot the web service seeds this user as an admin in the database.
# Afterwards the user record in SQLite is authoritative: changing the hash in
# env does NOT rotate the DB password — use the /einstellungen UI.
AUTH_USERNAME: str = _required("AUTH_USERNAME")
AUTH_PASSWORD_HASH: str = _required("AUTH_PASSWORD_HASH")
# --- Session cookie -----------------------------------------------------------
SESSION_SECRET: str = getenv("SESSION_SECRET") or secrets.token_urlsafe(48)
SESSION_COOKIE_NAME: str = "lazyflat_session"
SESSION_MAX_AGE_SECONDS: int = int(getenv("SESSION_MAX_AGE_SECONDS", str(60 * 60 * 24 * 7)))
COOKIE_SECURE: bool = getenv("COOKIE_SECURE", "true").lower() in ("true", "1", "yes", "on")
# --- Internal service auth ----------------------------------------------------
INTERNAL_API_KEY: str = _required("INTERNAL_API_KEY")
# --- Apply service ------------------------------------------------------------
APPLY_URL: str = getenv("APPLY_URL", "http://apply:8000")
APPLY_TIMEOUT: int = int(getenv("APPLY_TIMEOUT", "600"))
APPLY_FAILURE_THRESHOLD: int = int(getenv("APPLY_FAILURE_THRESHOLD", "3"))
# --- Alert service knob (mirrored so web can predict the next scrape) ---------
ALERT_SCRAPE_INTERVAL_SECONDS: int = int(getenv("ALERT_SCRAPE_INTERVAL_SECONDS", getenv("SLEEP_INTERVALL", "60")))
# --- Storage ------------------------------------------------------------------
DATA_DIR: Path = Path(getenv("DATA_DIR", "/data"))
DATA_DIR.mkdir(parents=True, exist_ok=True)
DB_PATH: Path = DATA_DIR / "lazyflat.sqlite"
# Retention (errors / audit / application forensics). Default 14 days.
RETENTION_DAYS: int = int(getenv("RETENTION_DAYS", "14"))
RETENTION_RUN_INTERVAL_SECONDS: int = int(getenv("RETENTION_RUN_INTERVAL_SECONDS", str(60 * 60)))
# --- Rate limiting ------------------------------------------------------------
LOGIN_RATE_LIMIT: int = int(getenv("LOGIN_RATE_LIMIT", "5"))
LOGIN_RATE_WINDOW_SECONDS: int = int(getenv("LOGIN_RATE_WINDOW_SECONDS", "900"))
# --- App URL (used to build links in notifications) ---------------------------
PUBLIC_URL: str = getenv("PUBLIC_URL", "https://flat.lab.moritz.run")
# --- LLM enrichment (Anthropic Haiku) -----------------------------------------
ANTHROPIC_API_KEY: str = getenv("ANTHROPIC_API_KEY", "")
ANTHROPIC_MODEL: str = getenv("ANTHROPIC_MODEL", "claude-haiku-4-5-20251001")
# --- Build info --------------------------------------------------------------
# Coolify injects SOURCE_COMMIT into the container's runtime env on every
# deploy; docker-compose.yml maps it to GIT_COMMIT. Rendered in the site
# footer so the running commit is visible at a glance.
GIT_COMMIT: str = getenv("GIT_COMMIT", "").strip() or "dev"