Configuration

Application settings come from environment variables — set them in the shell, a systemd unit, or .env files (KEY=VALUE, one per line). No YAML or other config format.

Load order

  1. Defaults (in code)
  2. User config file (if present): see below
  3. Project / CWD .env (when running from source or from a deployment directory)
  4. Environment variables (always override)

So: env vars override .env; .env overrides user config file; user config overrides defaults.

User-level config (.env file)

When using the installed package (e.g. rediflow run), the app looks for a user config file and then for a .env in the current working directory.

  • Explicit path: set REDIFLOW_CONFIG to the full path of a .env file (e.g. /etc/rediflow/config.env or ~/my.env).
  • Default path (no env set):
    • Linux / macOS: $XDG_CONFIG_HOME/rediflow/config.env or, if that is unset, ~/.config/rediflow/config.env
    • Windows: %APPDATA%\rediflow\config.env

Create the directory and file if you want to use it (e.g. mkdir -p ~/.config/rediflow then create config.env with DATABASE_URL=..., SECRET_KEY=..., etc.). Only variables not already set in the environment are applied from the file.

Project / deployment directory (.env)

When you run from the source tree (e.g. python main.py run), the app loads from the project root: .env.<APP_ENV>, .env.dev, or .env (first found). When you run the installed rediflow CLI, it also loads from the current working directory in the same order. So in a deployment directory (or in Podman with WORKDIR /app), place .env, .env.qa, or .env.dev and the app will use it.

Deployment with compose: Place .env.qa or .env.prod in the same directory as the compose file. Compose reads env_file relative to the compose file location. Compose also loads .env by default for variable substitution; create .env with POSTGRES_USER, POSTGRES_PASSWORD, and POSTGRES_DB matching your env file, or source the env file before running compose. See Deploy QA and production for the full guide.

Example .env files

  • Dev: copy .env.dev.example (in repo root) to .env.dev (or .env) and set DATABASE_URL, SECRET_KEY, etc.
  • QA: copy .env.qa.example to .env.qa. When using Podman Compose, set DATABASE_URL so the host is the service name db, e.g. postgresql://rediflow:rediflow@db:5432/rediflow_qa. Compose overrides this via the environment section if you use the same variable names.

Running migrations

After setting DATABASE_URL, run schema migrations before starting the app.

From source (local):

uv run python main.py migrate

Or: uv run rediflow migrate head.

From container (dev, with compose):

make migrate

Or explicitly: podman run --rm --network rediflow_default --env-file .env.dev -e DATABASE_URL=postgresql://...@db:5432/rediflow rediflow:latest rediflow migrate head. Use docker instead of podman if you use Docker.

From container (QA or production):

podman compose -f compose.deploy-qa.yml run --rm app-qa rediflow migrate head

For production, use compose.deploy-prod.yml and service app-prod. See Deploy QA and production for the full guide.

Main variables

Variable Required Description
DATABASE_URL Yes PostgreSQL URL (e.g. postgresql://user:pass@host:5432/dbname). Use postgresql+psycopg:// if you need the psycopg driver explicitly.
SECRET_KEY Yes in prod Flask secret; use a strong value in QA/prod.
APP_ENV No dev, qa, or prod (default dev).
LANG No Default UI locale (e.g. en, fi).
SUPPORTED_LOCALES No Comma-separated locales for the language dropdown.
PERSON_CAPACITY_ENABLED No true / false; enable People, Team, capacity (default false).
ROLE_DEMAND_ENABLED No When person capacity on, show Role demand / Roles capacity (default true).
CAPACITY_REQUESTS_ENABLED No When person capacity on, enable capacity requests (default true).
SHARE_URL_FEATURE No true / false; enable "Share" button to create short links and copy to clipboard (default true).
SHARE_URL_FEATURE_STATS No true / false; show Share link stats under Settings (default true).
SHARE_URL_STATS_MIN_CLICKS No Minimum click count to show a link in stats (default 10).
DEMAND_DEVIATION_ENABLED No true / false; show deviation of realised (EST/Actual) vs planned demand on Capacity and Graph (default false).
DEMAND_DEVIATION_MINOR_PCT No Normal/minor boundary in % (0–50, default 2.0). User can override in Settings → User preferences.
DEMAND_DEVIATION_MAJOR_PCT No Minor/major boundary in % (0–50, default 7.0). User can override in Settings → User preferences.
REDIFLOW_LICENSE_FILE No Path to a signed registration license file (Ed25519). If valid and not expired, the footer shows "Registered installation".
REDIFLOW_LICENSE No Inline signed license string (alternative to file). If both are set, the inline value is used.
REGISTRATION_URL No URL for the "Register (free)" link in the footer when the installation is unregistered (e.g. your form or landing page).
DEFAULT_COUNTRY_CODE No Default country for calendars (when org and its ancestors have no country code). ISO code e.g. FI, SE (default FI). Overridable in Settings → Calendars. Child orgs inherit from the nearest ancestor.
SOURCE_URL No Repository URL for the footer "Source" link (default: upstream GitLab). Set empty to hide.
DOCS_URL No Documentation site URL (GitLab Pages). Default derived from SOURCE_URL (e.g. https://rediflow_eu.gitlab.io/rediflow). Set empty to hide the docs link in Help and Settings.
SESSION_TRACE_ENABLED No true / false; when true, assign a correlation ID per session and log each request path. Enables "what did the user do before the error?" lookup for support (default false).

Row Level Security (RLS)

When using Authentik (OIDC), the app sets the PostgreSQL session variable app.current_user_id per request. RLS policies on user_settings and shared_views restrict access by user. When no user is logged in (or OIDC is disabled), the variable is empty and policies allow full access for backward compatibility.

RLS policies apply only when the app connects as a non-owner role. By default, the app uses the same role that runs migrations (table owner), so RLS is bypassed. To enable RLS, use a two-role setup.

RLS variables

Variable Required Description
RLS_ENABLED No true / false; when true, app connects as DATABASE_URL_APP role (default false).
DATABASE_URL_APP When RLS PostgreSQL URL for the app role (e.g. postgresql://rediflow_app:pass@host:5432/dbname). Must have SELECT/INSERT/UPDATE/DELETE on tables but not own them.
POSTGRES_APP_USER When RLS Username for the app role (e.g. rediflow_app). Used by compose to build DATABASE_URL_APP.
POSTGRES_APP_PASSWORD When RLS Password for the app role.

Two-role setup

  1. Owner role (e.g. rediflow): Runs migrations, owns tables. Use DATABASE_URL for migrations.
  2. App role (e.g. rediflow_app): Has grants only. Use DATABASE_URL_APP for the app when RLS_ENABLED=true.

Steps to enable RLS:

  1. Run migrations as owner: uv run python main.py migrate head (uses DATABASE_URL).
  2. Create the app role and grant permissions: uv run rediflow setup-rls-app-role (requires DATABASE_URL, POSTGRES_APP_USER, POSTGRES_APP_PASSWORD).
  3. Set RLS_ENABLED=true and DATABASE_URL_APP in your .env.
  4. Restart the app.

See Authentik setup for the full RLS flow with Authentik and .env.test.

Registration and license: Providing no license or an expired/invalid license does not restrict use of the software or any feature. The app works fully in all cases. Only the footer text differs: "Unregistered installation · Register (free)" vs "Registered installation." See Registration and license for license format and how to obtain a license.

See .env.dev.example and .env.qa.example in the repo root for the full list and comments.