Protect .env.qual from CI/CD Overwrites¶
Problem¶
The .env.qual file on VPS keeps getting overwritten by CI/CD, changing IMAGE_TAG=latest to IMAGE_TAG=<commit-sha>.
Root Cause¶
The CI/CD pipeline (.gitlab-ci/infrastructure.yml) was:
1. Generating .env.qual from env.qualification.ci template with IMAGE_TAG=${CI_COMMIT_SHORT_SHA}
2. Overwriting the file on VPS via scp
Every CI/CD run would replace your manually configured IMAGE_TAG=latest with a commit SHA.
Solution¶
1. CI/CD No Longer Overwrites .env.qual ✅¶
Changed: .gitlab-ci/infrastructure.yml
- Removed: scp .env.qual step that overwrote the file
- Added: Comment explaining why we skip the transfer
- Result: CI/CD uses environment variables instead
2. Template Updated ✅¶
Changed: infrastructure/env-templates/env.qualification.ci
- Before: IMAGE_TAG=${CI_COMMIT_SHORT_SHA} (commit SHA)
- After: IMAGE_TAG=latest (for manual deployments)
- Result: Even if template is used, it defaults to latest
3. CI/CD Uses Environment Variables ✅¶
CI/CD now uses:
export IMAGE_TAG="${CI_COMMIT_SHORT_SHA}"
IMAGE_TAG="${IMAGE_TAG}" docker compose -f qualification.yml --env-file .env.qual up -d
This means:
- .env.qual can have IMAGE_TAG=latest
- CI/CD overrides with environment variable IMAGE_TAG=<commit-sha>
- Manual deployments use IMAGE_TAG=latest from .env.qual
How It Works Now¶
Manual Deployments¶
# .env.qual has IMAGE_TAG=latest (locked)
docker compose -f qualification.yml --env-file .env.qual up -d
# Uses: IMAGE_TAG=latest
CI/CD Deployments¶
# CI/CD exports IMAGE_TAG and passes to docker compose
export IMAGE_TAG="${CI_COMMIT_SHORT_SHA}"
IMAGE_TAG="${IMAGE_TAG}" docker compose -f qualification.yml --env-file .env.qual up -d
# Uses: IMAGE_TAG=<commit-sha> (from environment, overrides .env.qual)
Protecting .env.qual on VPS¶
Option 1: Make File Read-Only (Recommended)¶
# On VPS
cd /opt/po-platform
# Set IMAGE_TAG=latest
sed -i 's/^IMAGE_TAG=.*/IMAGE_TAG=latest/' .env.qual
# Make read-only (prevents accidental changes)
chmod 444 .env.qual
# Verify
grep IMAGE_TAG .env.qual
# Should show: IMAGE_TAG=latest
Option 2: Add Comment¶
# On VPS
cd /opt/po-platform
# Edit .env.qual and add comment
# IMAGE_TAG=latest # DO NOT CHANGE - Locked for manual deployments
Option 3: Use Git (Track Changes)¶
# On VPS
cd /opt/po-platform
# Add .env.qual to git (if not already tracked)
git add .env.qual
git commit -m "Lock IMAGE_TAG=latest for manual deployments"
# If file gets changed, restore from git
git checkout .env.qual
Verification¶
After fixes:
# On VPS - Verify IMAGE_TAG is locked
grep IMAGE_TAG .env.qual
# Should show: IMAGE_TAG=latest
# After CI/CD runs, check file wasn't overwritten
cat .env.qual | grep IMAGE_TAG
# Should still show: IMAGE_TAG=latest (not commit SHA)
CI/CD Behavior¶
Before Fix:
- CI/CD generates .env.qual with IMAGE_TAG=9ca7c8cd
- Overwrites VPS file via scp
- Your IMAGE_TAG=latest is lost
After Fix:
- CI/CD skips .env.qual transfer
- Uses environment variable IMAGE_TAG="${CI_COMMIT_SHORT_SHA}"
- VPS .env.qual stays as IMAGE_TAG=latest
- Manual deployments work correctly
Related¶
- Immutable Files Architecture - Architecture principles
- Fix Image Tag Issue - Troubleshooting guide
- ARCHITECTURE-SUMMARY - Implementation summary