Skip to main content

Environment Variables & Configuration

This document describes the hierarchical configuration system used in Syntropy-Journals.

Architecture Overview

Syntropy-Journals uses Hydra (OmegaConf) for hierarchical YAML-based configuration, combined with environment variable overrides loaded from envs/ files.
+---------------------------------------------------------------+
|  Hydra Config Layer (app/config/*.yaml + hydra_config.py)     |
|  +----------+ +----------+ +----------+ +----------+          |
|  |   app    | |   llm    | |   ui     | |  admin   | ...      |
|  |  config  | |  config  | |  config  | |  config  |          |
|  +----+-----+ +----+-----+ +----+-----+ +----+-----+          |
|       |            |            |            |                 |
|       +------------+------+-----+------------+                 |
|                           |                                    |
|                    +------v------+                              |
|                    |  Typed DC   |  (dataclass getters)         |
|                    +------+------+                              |
+---------------------------+------------------------------------+
                            |
+---------------------------v------------------------------------+
|  Environment Loading (rxconfig.py)                             |
|                                                                |
|  Load Order (later overrides earlier):                         |
|  1. envs/base       -- Shared non-secret config               |
|  2. envs/{APP_ENV}  -- Environment-specific overrides          |
|  3. .env            -- Local secrets (gitignored)              |
+----------------------------------------------------------------+

File Structure

envs/
+-- template.base      # Template for envs/base (committed)
+-- template           # Template for envs/{APP_ENV} (committed)
+-- base               # Shared config (created from template.base)
+-- dev                # Dev overrides (created from template)
+-- test               # Test overrides
+-- prod               # Production overrides
Templates are committed to git; actual envs/base and envs/dev are created via make env-dev.

Key Environment Variables

Application Core

VariableDescriptionDefault
APP_ENVEnvironment name (dev/test/prod)dev
LOGLEVELLog levelINFO

Database

VariableDescriptionDefault
REFLEX_DB_URLFull PostgreSQL connection URLpostgresql://postgres:postgres@localhost:5432/syntropy_journals

Authentication (Clerk)

VariableDescriptionExample
CLERK_PUBLISHABLE_KEYFrontend keypk_test_...
CLERK_SECRET_KEYBackend keysk_test_...

LLM / AI

VariableDescriptionDefault
OPENROUTER_API_KEYOpenRouter API key (primary LLM provider)(required)

Payments (Stripe)

VariableDescriptionExample
STRIPE_SECRET_KEYStripe secret keysk_test_...
STRIPE_PUBLISHABLE_KEYStripe publishable keypk_test_...

Deployment

VariableDescriptionDefault
REFLEX_API_URLBackend public URL-
REFLEX_DEPLOY_URLFrontend public URL-
CORS_ALLOWED_ORIGINSComma-separated CORS origins-

Analytics & Tracking

VariableDescriptionDefault
GA_MEASUREMENT_IDGoogle Analytics 4 measurement IDG-K6TR1P8KFZ
GTM_CONTAINER_IDGoogle Tag Manager container IDGTM-58ZTSM22
GTM_ONLYEnable GTM-only mode (minimal UI)false
POSTHOG_PROJECT_API_KEYPostHog project API key(empty = disabled)
POSTHOG_HOSTPostHog instance URLhttps://us.i.posthog.com
POSTHOG_ENABLEDEnable/disable PostHogtrue

Health Data (Junction/Vital)

VariableDescriptionDefault
JUNCTION_API_KEYJunction (Vital) API key for wearable data(empty = disabled)
JUNCTION_ENVIRONMENTJunction environment: sandbox, production, sandbox_eu, production_eusandbox
When JUNCTION_API_KEY is absent, all wearable features are silently disabled — no crash, no error. See junction-wearables.md for details.

Config Access (Hydra)

Configuration is accessed via typed getter functions in syntropy_journals/app/hydra_config.py:
from syntropy_journals.app.hydra_config import (
    get_app_config,
    get_llm_config,
    get_chat_config,
    get_theme_config,
    get_branding_config,
)

# Examples
app_cfg = get_app_config()
llm_cfg = get_llm_config()
model_name = llm_cfg.model_name

Hydra YAML Files

FileDataclassDescription
app/config/app/default.yamlAppConfigApp-level settings
app/config/llm/default.yamlLLMConfigLLM model, temperature, etc.
app/config/ui/default.yamlUIConfigUI feature flags
app/config/admin/default.yamlAdminConfigAdmin settings
app/config/head/default.yamlHeadConfigHTML head components

Setup

Create local environment files

make env-dev
This copies envs/template.base to envs/base and envs/template to envs/dev. Then edit them with your actual keys.

Required for development

At minimum, set these in envs/dev or .env:
CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
OPENROUTER_API_KEY=sk-or-...

Required for payments

STRIPE_SECRET_KEY=sk_test_...
STRIPE_PUBLISHABLE_KEY=pk_test_...

Railway / Docker Deployment

Environment variables set in Railway or Docker take precedence over envs/ files. The rxconfig.py loader preserves pre-existing environment variables:
# Critical vars are captured BEFORE loading envs/ files
# and restored AFTER, ensuring Railway/Docker vars win
critical_vars = [
    "APP_ENV", "REFLEX_DB_URL",
    "CLERK_PUBLISHABLE_KEY", "CLERK_SECRET_KEY",
    ...
]

Troubleshooting

Config not loading?

# Check which environment is active
echo $APP_ENV

# Test config loading
APP_ENV=dev uv run python -c "
from syntropy_journals.app.hydra_config import get_app_config
cfg = get_app_config()
print(cfg)
"

Hydra ConfigAttributeError?

Attributes not present in the YAML file will raise ConfigAttributeError even if defined as dataclass defaults. Always add new config keys to both the dataclass AND the YAML file.

Wrong environment?

Ensure APP_ENV is set before starting the app:
APP_ENV=dev make dev
APP_ENV=test make test