Immutable Files Architecture¶
Principle¶
Compose files and .env files are immutable - they are never modified by scripts or CI/CD. All customization happens via environment variables passed at runtime.
Architecture¶
Compose Files (Immutable)¶
Location: infrastructure/compose/*.yml
Status: ✅ READ-ONLY - Never modified by scripts
How they work:
- Use environment variable substitution: ${IMAGE_TAG:-latest}
- Read from .env files via env_file directive
- Can be overridden by environment variables at runtime
Example:
Runtime override:
Environment Files (Generated, Not Modified)¶
Location: infrastructure/compose/.env.* and .env.*
Status: ✅ GENERATED FROM TEMPLATES - Never modified after generation
Generation:
- Created from templates in infrastructure/env-templates/
- Generated by generate-secrets.sh script
- Templates use placeholders like REPLACE_ME_STRONG_PASSWORD
After generation: - Files are never modified by scripts - Manual edits are allowed (for external API keys) - CI/CD generates fresh files from templates (doesn't modify existing)
CI/CD Process¶
Before (❌ Bad - Modified Files)¶
# OLD: Modified compose file
bash infrastructure/scripts/update-image-tags.sh qual "${IMAGE_TAG}"
docker compose -f qualification.yml up -d
Problem: Compose file gets modified with hardcoded tags
After (✅ Good - Uses Environment Variables)¶
# NEW: Uses environment variables
export IMAGE_TAG="${CI_COMMIT_SHORT_SHA}"
IMAGE_TAG="${IMAGE_TAG}" docker compose -f qualification.yml --env-file .env.qual up -d
Benefit: Compose file stays unchanged, uses environment variable
Scripts That Generate Files (Allowed)¶
These scripts generate files from templates (OK):
generate-secrets.sh- Generates
.env.shared,.env.qualification,.env.productionfrom templates -
✅ Allowed - creates new files from templates
-
CI/CD
.env.qualgeneration - Generates
.env.qualfromenv.qualification.citemplate - ✅ Allowed - creates new file from template
Scripts That Modify Files (Not Allowed)¶
These scripts modify existing files (NOT ALLOWED):
update-image-tags.sh❌- Status: Deprecated for manual use
- CI/CD: Still used but should be removed
-
Action: Use environment variables instead
-
Any script using
sedon compose files ❌ - Status: Not allowed
- Action: Use environment variables
Best Practices¶
For Manual Deployments¶
# 1. Ensure .env.qual has IMAGE_TAG=latest
grep IMAGE_TAG .env.qual
# 2. Use environment variable (optional override)
IMAGE_TAG=latest docker compose -f qualification.yml --env-file .env.qual up -d
# 3. Compose file uses ${IMAGE_TAG:-latest} which reads from .env.qual
For CI/CD Deployments¶
# 1. Export IMAGE_TAG as environment variable
export IMAGE_TAG="${CI_COMMIT_SHORT_SHA}"
# 2. Pass to docker compose (overrides .env file)
IMAGE_TAG="${IMAGE_TAG}" docker compose -f qualification.yml --env-file .env.qual up -d
# 3. Compose file uses ${IMAGE_TAG:-latest} which reads from environment
For Script Development¶
✅ DO:
- Read compose files
- Read .env files
- Generate new files from templates
- Use environment variables for customization
❌ DON'T:
- Modify compose files with sed or similar
- Modify .env files after generation
- Hardcode values in compose files
- Use update-image-tags.sh for manual deployments
Verification¶
Check Compose Files Are Immutable¶
# Check git status - compose files should never show as modified
git status infrastructure/compose/*.yml
# Should show: nothing (or only intentional changes)
Check .env Files Are Generated, Not Modified¶
# .env files should be generated from templates
diff <(grep -v "^#" infrastructure/env-templates/env.qualification.template | sort) \
<(grep -v "^#" infrastructure/compose/.env.qualification | sort)
# Differences should only be:
# - Generated secrets (passwords)
# - Manual edits (external API keys)
Verify Environment Variable Usage¶
# Compose files should use ${VARIABLE:-default} syntax
grep -E '\$\{[A-Z_]+\}' infrastructure/compose/qualification.yml
# Should show variables like:
# ${REGISTRY_IMAGE:-...}
# ${IMAGE_TAG:-latest}
# ${POSTGRES_PASSWORD_QUAL}
Migration Guide¶
If you have scripts that modify files:
-
Identify the modification
-
Replace with environment variables
-
Update CI/CD
See Also¶
- Fix Image Tag Issue - Troubleshooting guide
- CI/CD Pipeline - CI/CD documentation
- Environment Setup - Environment configuration