π‘ ExamplesΒΆ
Complete .env-fuse configuration examples. For tool-specific usage, see Workflows.
π Web Application with Multi-EnvironmentΒΆ
Full-featured web app setup with environment-specific configuration, imports, conditionals, type system, and validation.
.env-fuse
#@def APP_NAME required=true doc="Application name"
#@def ENV required=true validate=^(dev|staging|production)$ doc="Environment"
#@def PORT type=int default=3000 doc="HTTP port"
#@def DEBUG type=bool default=false doc="Debug mode"
APP_NAME=MyWebApp
ENV=production
# Import base configuration
#@import configs/base.env
# Import environment-specific config (dynamic path!)
#@import configs/${ENV}.env
# Import local overrides if present (optional)
#@import .env-fuse.local mode=ifexist
# Environment-specific secrets with conditionals
#@if ${ENV} == production
#@import secrets/prod.env prefix=SECRET_
LOG_LEVEL=error
DEBUG=false
#@else
#@import secrets/dev.env prefix=SECRET_
LOG_LEVEL=debug
DEBUG=true
#@endif
# Variable expansion for service URLs
BASE_URL=https://api.example.com
API_URL=${BASE_URL}/v1
STATIC_URL=${BASE_URL}/static
#@if ${ENV} == development
BASE_URL=http://localhost:${PORT}
API_URL=${BASE_URL}/api
#@endif
π Usage:
eval "$(dotenv-fusion load -f .env-fuse)"
echo $APP_NAME # MyWebApp
echo $PORT # 3000 (int)
echo $DEBUG # false (bool)
echo $LOG_LEVEL # error (from conditional)
echo $API_URL # https://api.example.com/v1
echo $WORKERS # 4 (from configs/base.env)
π Python integration:
from dotenv_fusion import load_dotenv
config = load_dotenv(".env-fuse")
# Start Flask app
from flask import Flask
app = Flask(__name__)
app.config.update({
'PORT': config['PORT'],
'DEBUG': config['DEBUG'],
'SECRET_KEY': config['SECRET_API_KEY']
})
if __name__ == '__main__':
app.run(port=config['PORT'], debug=config['DEBUG'])
β¨ What makes this powerful:
- β
Multi-environment with dynamic imports (
configs/${ENV}.env) - β Type system (PORT as int, DEBUG as bool)
- β Validation (ENV must be dev/staging/production)
- β Conditionals (#@if for secrets and URLs)
- β Optional imports (.env-fuse.local)
- β Variable expansion (BASE_URL β API_URL)
- β Prefixes for secrets (SECRET_*)
π§ Microservices with Clean NamespaceΒΆ
Organize configuration for multiple services with prefixes - no variable name conflicts.
.env-fuse
SERVICE_NAME=user-service
NAMESPACE=production
# Import all services with prefixes - clean namespace!
#@import services/postgres.env prefix=DB_
#@import services/redis.env prefix=CACHE_
#@import services/rabbitmq.env prefix=MQ_
#@import services/s3.env prefix=STORAGE_
# Build service URLs from imported variables
DB_URL=postgresql://${DB_HOST}:${DB_PORT}/${DB_NAME}
CACHE_URL=redis://${CACHE_HOST}:${CACHE_PORT}/${CACHE_DB}
MQ_URL=amqp://${MQ_HOST}:${MQ_PORT}/${MQ_VHOST}
STORAGE_URL=s3://${STORAGE_BUCKET}/${STORAGE_PREFIX}
services/postgres.env
HOST=postgres.production.svc.cluster.local
PORT=5432
NAME=userdb
USER=admin
PASSWORD=secret
services/rabbitmq.env
HOST=rabbitmq.production.svc.cluster.local
PORT=5672
VHOST=/production
USER=app
PASSWORD=secret
π Result:
DB_HOST=postgres.production.svc.cluster.local
DB_PORT=5432
DB_NAME=userdb
DB_URL=postgresql://postgres.production.svc.cluster.local:5432/userdb
CACHE_HOST=redis.production.svc.cluster.local
CACHE_PORT=6379
CACHE_DB=0
CACHE_URL=redis://redis.production.svc.cluster.local:6379/0
MQ_HOST=rabbitmq.production.svc.cluster.local
MQ_URL=amqp://rabbitmq.production.svc.cluster.local:5672/production
β¨ What makes this powerful:
- β Clear separation with prefixes (DB*, CACHE*, MQ*, STORAGE*)
- β No variable name conflicts
- β Easy to understand which variable belongs to which service
- β Modular service configuration files
- β Variable expansion to build URLs
π Branch-Aware Deployment ConfigurationΒΆ
Advanced conditional logic and variable expansion for CI-provided values with local fallbacks.
.env-fuse
#@def BRANCH doc="Git branch name"
BRANCH=${CI_COMMIT_BRANCH:-main}
#@def COMMIT doc="Git commit SHA"
COMMIT=${CI_COMMIT_SHA:-local}
# CI detection
#@ifdef CI
#@import ci/test.env override=true
CI_MODE=true
#@endif
# Dynamic environment based on branch
#@if ${BRANCH} == main
DEPLOY_ENV=production
DEPLOY_URL=https://app.example.com
#@endif
#@if ${BRANCH} == staging
DEPLOY_ENV=staging
DEPLOY_URL=https://staging.example.com
#@endif
#@ifndef DEPLOY_ENV
DEPLOY_ENV=preview
DEPLOY_URL=https://${BRANCH}.preview.example.com
#@endif
# Container image with dynamic tags
REGISTRY=${CI_REGISTRY:-docker.io}
PROJECT_PATH=${CI_PROJECT_PATH:-myorg/myapp}
IMAGE=${REGISTRY}/${PROJECT_PATH}:${COMMIT}
# Feature flags
#@ifdef FEATURE_BETA_API
API_VERSION=v2
API_ENDPOINT=/api/v2
#@else
API_VERSION=v1
API_ENDPOINT=/api/v1
#@endif
ci/test.env
DATABASE_URL=postgresql://testdb:5432/test
REDIS_URL=redis://testredis:6379
LOG_LEVEL=debug
WORKERS=2
π Example resolved values:
BRANCH=main
COMMIT=abc123
DEPLOY_ENV=production
DEPLOY_URL=https://app.example.com
IMAGE=docker.io/myorg/myapp:abc123
β¨ What makes this powerful:
- β Works locally (with defaults) and in CI (with CI_ vars)
- β Dynamic deployment URLs based on branch
- β Conditional overrides for testing (#@ifdef CI)
- β Feature flags with ifdef
- β Variable expansion from system environment
- β
Multiple conditionals with
#@ifdef/#@ifndeffor multi-branch logic