# Petal — copy to .env and fill in. All values have local-dev defaults; override as needed. # Server PORT=8080 BASE_URL=http://localhost:8080 # Database (SQLite, pure-Go modernc — no cgo) DATABASE_PATH=./data/petal.db # On-disk store for images pasted/dropped/inserted in the editor IMAGE_DIR=./data/images # DreamDict's built dictionary (French, European Portuguese, Spanish, Mandarin), # opened read-only beside petal.db. Optional: with no file here, word lookups use # the embedded English/Chinese datasets, which is how a laptop checkout runs. # Build one with `go run ./cmd/dictimport` in the dreamdict repo. DICT_PATH=./data/dict.db # LLM LLM_BACKEND=vllm # vllm | ollama LLM_ENDPOINT=http://localhost:8000 # vLLM :8000, Ollama :11434 LLM_MODEL= # checkpoint model (small/fast). Never hardcoded. LLM_CHAT_MODEL= # Ask Petal model (Mandarin-native). Falls back to LLM_MODEL if empty. LLM_TIMEOUT=30s # Read-aloud (TTS). Off unless TTS_ENDPOINT is set — when empty, the /api/tts route # is not mounted and the frontend falls back to the browser's Web Speech API. # Backed by a local Piper HTTP server (python3 -m piper.http_server). # Each Piper HTTP server loads ONE voice, so English and Chinese need separate # instances (different ports). zh is only routed when both TTS_ENDPOINT_ZH and # TTS_VOICE_ZH are set; otherwise Chinese falls back to Web Speech. TTS_ENDPOINT= # e.g. http://127.0.0.1:5005 — empty disables server TTS TTS_ENDPOINT_ZH= # e.g. http://127.0.0.1:5006 — Chinese Piper instance TTS_VOICE_EN=en_US-amy-medium # Piper voice id for English TTS_VOICE_ZH=zh_CN-huayan-medium # Piper voice id for Chinese TTS_PATH=/ # path Piper serves synthesis on: "/" up to piper-tts 1.5, "/synthesize" from 1.6.0 TTS_CACHE_DIR=./data/tts # on-disk store for synthesized clips (content-addressed) TTS_TIMEOUT=15s TTS_AUDIO_FORMAT=mp3 # mp3 | opus | wav — mp3/opus transcode Piper's WAV via ffmpeg # --- Auth (Authentik OIDC) --- # # Login turns on only when the issuer, client id and secret are all set. Leave # them commented out for local development and Petal runs as the single # hardcoded `local` user, exactly as it did before auth landed. # # That fallback is scoped to development on purpose. With a BASE_URL naming # anything but localhost, Petal refuses to start rather than run open — see # PETAL_REQUIRE_AUTH — because the fallback on a reachable host means every # anonymous visitor is the `local` user, with full read and write over every # document in the database. # # AUTHENTIK_URL is the issuer of the Petal provider in Authentik (the value of # its "OpenID Configuration Issuer" field). The redirect URI to register there # is BASE_URL + /auth/callback. # AUTHENTIK_URL=https://auth.parodia.dev/application/o/petal/ # AUTHENTIK_CLIENT_ID=petal # AUTHENTIK_CLIENT_SECRET= # # Who may sign in: comma-separated OIDC subject ids and/or email addresses. # Empty = anyone Authentik authenticates, which is right for a single-household # instance and wrong the moment the IdP serves a wider audience than Petal. An # empty list is warned about at every boot rather than assumed either way. # PETAL_ALLOWED_SUBS=her@example.com,me@example.com # # Whether a missing OIDC configuration is fatal. Defaults to false for a # loopback BASE_URL and true for anything else, so neither a laptop nor a # deployment normally has to name it. # PETAL_REQUIRE_AUTH=true # --- Deferred (not wired in the local-dev build) --- # Copyleaks (Tier-2 plagiarism) — deferred; needs a public webhook # COPYLEAKS_ENABLED=false # COPYLEAKS_API_KEY= # COPYLEAKS_EMAIL=