Immutable Files Architecture - Implementation Complete ✅¶
⚠️ Historical doc. Describes the 2025-01 deploy-script architecture that wrapped
infrastructure/scripts/ci-deploy.sh. That script and themake deploy-{shared,qual,prod}targets were retired in Riff#50(2026-04-30). Current deploy doctrine: GitLab CI auto-deploys qual on push to main; prod is a manual CI job (Riff#10). Seedocs/reference/makefile.mdfor the current Makefile surface.
Summary¶
All compose files and .env files are now immutable - they are never modified by scripts or CI/CD processes. All customization happens via environment variables passed at runtime.
Changes Made¶
1. CI/CD Refactored ✅¶
File: .gitlab-ci/infrastructure.yml
Before:
# ❌ Modified compose file
bash infrastructure/scripts/update-image-tags.sh qual "${IMAGE_TAG}"
docker compose -f qualification.yml up -d
After:
# ✅ 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
Result: Compose files are never modified by CI/CD.
2. Scripts Updated ✅¶
update-image-tags.sh:- Marked as DEPRECATED
- Only works in CI/CD (safety check prevents manual use)
-
Should not be used - use environment variables instead
-
ci-deploy.sh: - Already uses environment variables correctly ✅
-
No changes needed
-
generate-secrets.sh: - ✅ OK - Generates files from templates (doesn't modify existing)
- This is the intended way to create
.envfiles
3. Documentation Created ✅¶
docs/devops/deployment/immutable-files-architecture.md- Complete architecture guideinfrastructure/compose/README.md- Compose files documentationdocs/devops/deployment/fix-image-tag-issue.md- Troubleshooting guide
Architecture Principles¶
Compose Files: IMMUTABLE ✅¶
Status: Never modified by any script or CI/CD
How they work:
Variables read from:
1. .env files (via env_file directive)
2. Environment variables (passed at runtime, takes precedence)
Runtime override:
.env Files: GENERATED ✅¶
Status: Generated from templates, never modified after generation
Generation:
- Created from templates in infrastructure/env-templates/
- Generated by generate-secrets.sh script
- CI/CD generates fresh files from templates
After generation: - Files are never modified by scripts - Manual edits allowed (for external API keys like Stripe, AWS) - CI/CD generates fresh files (doesn't modify existing)
Customization: ENVIRONMENT VARIABLES ✅¶
All customization via environment variables at runtime:
CI/CD:
export IMAGE_TAG="${CI_COMMIT_SHORT_SHA}"
IMAGE_TAG="${IMAGE_TAG}" docker compose -f qualification.yml --env-file .env.qual up -d
Manual:
# .env.qual has IMAGE_TAG=latest (locked)
docker compose -f qualification.yml --env-file .env.qual up -d
Verification¶
✅ CI/CD Doesn't Modify Files¶
✅ Compose Files Use Variables¶
grep "IMAGE_TAG" infrastructure/compose/qualification.yml | head -1
# Output: image: .../service:${IMAGE_TAG:-latest}
✅ .env Files Are Generated¶
File Status¶
✅ Immutable (Never Modified)¶
infrastructure/compose/*.yml- All compose files.env.qual,.env.prod- After generation, only manual edits allowed
✅ Generated (From Templates)¶
infrastructure/compose/.env.shared- Fromenv.shared.templateinfrastructure/compose/.env.qualification- Fromenv.qualification.templateinfrastructure/compose/.env.production- Fromenv.production.template
❌ Deprecated (Don't Use)¶
update-image-tags.sh- Use environment variables instead
Usage Examples¶
Manual Deployment¶
# 1. Ensure .env.qual has IMAGE_TAG=latest
grep IMAGE_TAG .env.qual
# 2. Deploy (compose file reads from .env.qual)
docker compose -f qualification.yml --env-file .env.qual up -d
# 3. Optional: Override at runtime
IMAGE_TAG=custom-tag docker compose -f qualification.yml --env-file .env.qual up -d
CI/CD Deployment¶
# CI/CD automatically:
# 1. Exports IMAGE_TAG="${CI_COMMIT_SHORT_SHA}"
# 2. Passes to docker compose
# 3. Compose file uses environment variable (overrides .env file)
Benefits¶
- Predictable: Compose files never change unexpectedly
- Version Controlled: Compose files stay in sync with git
- Flexible: Easy to override with environment variables
- Maintainable: Clear separation between definition (compose) and configuration (.env)
- Safe: No risk of scripts corrupting compose files
Migration Notes¶
If you have existing deployments:
-
Restore compose files from git:
-
Ensure .env files have IMAGE_TAG:
-
Deploy using environment variables:
See Also¶
- Immutable Files Architecture - Detailed guide
- Fix Image Tag Issue - Troubleshooting
- CI/CD Pipeline - CI/CD documentation