The .git-COPY approach froma35e6c9never 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 stale0144cb2image 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>
67 lines
3 KiB
Python
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"
|