Environment files
Environment files (.env) define how a product connects to its infrastructure — database hostnames, ports, credentials, feature-specific service URLs, and runtime flags. They are the source of truth for runtime configuration.
Table of contents
- Why they matter
- File hierarchy
- Dev vs prod separation
- Merge flow
- Key variables
- Who reads them
- See also
Why they matter
The other sources of truth define what a product is made of (pyproject.toml), which combinations are valid (UVL), and what state features are in (manifest). Environment files define how it runs: which hostname the database listens on, which port Redis exposes, what credentials to use, and whether to seed the database on startup.
Without environment files, Docker containers cannot connect to each other, the framework cannot build a database URI, and features that depend on external services (mail, Redis, storage) cannot function.
File hierarchy
Each product and feature can declare environment files. During deployment, these are merged into a single configuration.
Product level
| File | Purpose | Git-tracked |
|---|---|---|
docker/.env.dev.example |
Template for development | Yes |
docker/.env.prod.example |
Template for production (credentials as <SET>) |
Yes |
docker/.env |
Active dev config (generated from example) | No |
docker/.env.deploy |
Active prod config (generated by product:deploy) |
No |
docker/.env.deploy.example |
Merged template (generated by product:build) |
No |
Feature level
| File | Purpose | Git-tracked |
|---|---|---|
docker/.env.example |
Default feature env template | Yes |
docker/.env.dev.example |
Dev-specific overrides | Yes |
docker/.env.prod.example |
Prod-specific overrides | Yes |
docker/.env |
Active config (generated by product:env) |
No |
Dev vs prod separation
Development and production use separate files to prevent configuration collisions:
- Dev reads from
docker/.env— contains dev hostnames (e.g.,sample_splent_app_db), default passwords, seeding enabled. - Prod reads from
docker/.env.deploy— contains deploy hostnames (e.g.,sample_splent_app_db_deploy), real credentials, seeding disabled.
The production entrypoint syncs .env.deploy to .env on startup so the framework’s load_dotenv() picks up the correct values.
Never commit
.envor.env.deployfiles with real credentials. Only commit.exampletemplates.
Merge flow
Development (product:env --merge --dev)
product/.env.dev.example + feature1/.env.example + feature2/.env.example
↓
product/docker/.env
Product values take priority (via setdefault). Features only add keys that the product doesn’t already define.
Production (product:build)
product/.env.prod.example + feature1/.env.example + feature2/.env.example
↓
product/docker/.env.deploy.example
Feature values override product values (via update). This allows features to inject their required variables (e.g., REDIS_URL, MAIL_SERVER).
Key variables
| Variable | Set by | Used by |
|---|---|---|
SPLENT_APP |
Product | CLI, framework, startup scripts |
SPLENT_ENV |
Developer/CI | CLI (feature resolution), startup scripts |
WORKING_DIR |
Docker | CLI, framework (path resolution) |
MARIADB_HOSTNAME |
Product env | Framework (database URI), startup scripts |
MARIADB_DATABASE |
Product env | Framework, migration scripts |
MARIADB_USER / MARIADB_PASSWORD |
Product env | Framework, health checks, startup scripts |
REDIS_URL |
Redis feature | Framework (session store), app code |
REDIS_HOST_PORT |
Redis feature | Docker Compose (port mapping) |
MAIL_SERVER / MAIL_PORT |
Mail feature | Framework (Flask-Mail), app code |
RUN_DB_SEED |
Product env | Startup script 04_handle_migrations.sh |
GUNICORN_WORKERS |
Operator | Production entrypoint (default: 2*nproc+1) |
GUNICORN_TIMEOUT |
Operator | Production entrypoint (default: 120) |
Who reads them
| Consumer | What it reads | Why |
|---|---|---|
product:env |
.env.example templates |
Generates and merges .env files |
product:build |
.env.prod.example from product + features |
Creates .env.deploy.example |
product:deploy |
.env.deploy.example |
Creates .env.deploy, prompts for <SET> values |
| Docker Compose | env_file: directive |
Injects vars into containers |
Framework load_dotenv |
<product>/docker/.env |
Overrides process env vars |
| Startup scripts | $MARIADB_*, $RUN_DB_SEED |
Database connection, seeding |
| Health checks | $$MARIADB_USER, $$MARIADB_PASSWORD |
Docker Compose CMD-SHELL |
See also
- pyproject.toml — feature declarations and versions
- product:env — generate and merge env files
- product:build — merge env + compose for production
- product:deploy — deploy with
.env.deploy