Configuration
Complete configuration reference for Joidy via environment variables.
Configuration
All configuration is done via environment variables in .env. After a git
clone, copy .env.example to .env; system installs (curl script, Homebrew,
AUR) keep it at ~/.config/joidy/.env.
Required
| Variable | Description |
|----------|-------------|
| GEMINI_API_KEY | Google Gemini API key — AI Studio. AI features are disabled without a provider key, but the app still works |
| OBSIDIAN_VAULT_PATH | Absolute host path to your Obsidian vault (~ is expanded). Mounted read-write at /vault in the worker |
| SECRET_KEY | Session/JWT signing key — generate with openssl rand -hex 32 |
AI Providers
Joidy supports 6 providers through a factory in ai-service. Set the API key
for the providers you want, then pick the active one with LLM_MODEL.
| Variable | Default | Description |
|----------|---------|-------------|
| GEMINI_API_KEY | — | Google Gemini |
| OPENAI_API_KEY | — | OpenAI |
| ANTHROPIC_API_KEY | — | Anthropic |
| COHERE_API_KEY | — | Cohere |
| OPENROUTER_API_KEY | — | OpenRouter |
| OLLAMA_BASE_URL | http://host.docker.internal:11434 | Local Ollama endpoint — no key needed |
| LLM_MODEL | gemini:gemini-2.0-flash | Active chat/classification model, provider:model format |
| EMBEDDING_MODEL | gemini:models/text-embedding-004 | Embedding model, provider:model format |
| AI_SERVICE_ENABLED | true | Set false to disable AI calls entirely |
Obsidian
| Variable | Description |
|----------|-------------|
| OBSIDIAN_VAULT_PATH | Host path to vault; also used by the API for vault file ops |
| OBSIDIAN_WEBHOOK_SECRET | Shared secret for POST /webhook/obsidian — enables instant push sync (see API Reference) |
Database
| Variable | Description |
|----------|-------------|
| POSTGRES_USER | joidy by default |
| POSTGRES_PASSWORD | Password for the postgres container. Only applies at initdb — changing it on an existing volume breaks auth unless you update the role in Postgres |
| POSTGRES_DB | joidy by default |
DATABASE_URL is composed automatically inside compose
(postgresql://joidy:<password>@postgres:5432/joidy).
Integrations (optional)
| Variable | Description |
|----------|-------------|
| GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET | GitHub OAuth app |
| GITHUB_TOKEN / GITHUB_USERNAME | Classic token sync alternative |
| GITHUB_OAUTH_WEB_URL / GITHUB_WEBHOOK_URL | OAuth callback base / webhook endpoint |
| GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET / GOOGLE_REDIRECT_URI | Google Calendar & Tasks OAuth (default redirect http://localhost:8000/integrations/google/callback) |
| STRAVA_CLIENT_ID / STRAVA_CLIENT_SECRET / STRAVA_REDIRECT_URI | Strava integration |
| SPOTIFY_CLIENT_ID / SPOTIFY_CLIENT_SECRET / SPOTIFY_REDIRECT_URI | Spotify integration |
| TELEGRAM_BOT_TOKEN / TELEGRAM_ALLOWED_USER_ID | Telegram notifications |
Push Notifications
| Variable | Description |
|----------|-------------|
| VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY | Web Push VAPID keypair — without it, push is disabled gracefully |
| VAPID_CLAIM_EMAIL | mailto: contact for the VAPID claim |
Server
| Variable | Default | Description |
|----------|---------|-------------|
| SECRET_KEY | — | JWT signing key (required) |
| APP_ENV | development | development or production |
| CORS_ALLOWED_ORIGINS | localhost dev fallback | Comma-separated allowed origins |
| AUTH_PASSWORD | — | Single-user password for POST /auth/login. Required when APP_ENV=production — the API refuses to start without it |
| FRONTEND_PORT / API_PORT / AI_SERVICE_PORT / WORKER_PORT | 3000 / 8000 / 8002 / 8001 | Host port overrides |
| GRAFANA_ADMIN_PASSWORD | — | Required only when using docker-compose.monitoring.yml |
Example .env
SECRET_KEY=change_this_to_a_random_secret_key
GEMINI_API_KEY=your-key
OBSIDIAN_VAULT_PATH=~/Documents/obsidian/my-vault
POSTGRES_PASSWORD=a-strong-password
# Optional
LLM_MODEL=gemini:gemini-2.0-flash
TELEGRAM_BOT_TOKEN=
CORS_ALLOWED_ORIGINS=http://localhost:3000
Generating SECRET_KEY
openssl rand -hex 32
# or
python -c "import secrets; print(secrets.token_hex(32))"