Upgrades & Rollback
Purpose: Ensure safe and reliable version management.
Contents
- Upgrade Strategy
- Pre-Upgrade Preparation
- Upgrade Execution
- Rollback Procedures
- Validation & Testing
- Sources
Upgrade Strategy
Tagging Policy:
- Production: Use specific version tags (e.g., 6.1.17
, 6.1.18
)
- Staging: Use release candidate tags (e.g., 6.1.18-rc1
)
- Development: Use specific commits or feature branches
- Never: Use latest
tag in any environment
Version Support Matrix:
Environment |
Upgrade Frequency |
Version Lag |
Approval Required |
Development |
Immediate |
Latest RC |
Developer |
Staging |
Weekly |
1-2 versions behind latest |
Team Lead |
Production |
Monthly |
2-4 versions behind latest |
Change Board |
Upgrade Types:
Type |
Example |
Database Changes |
Downtime |
Risk Level |
Patch |
6.1.17 → 6.1.18 |
Rare |
None |
Low |
Minor |
6.1.x → 6.2.0 |
Possible |
Minimal |
Medium |
Major |
6.x → 7.0 |
Likely |
Planned |
High |
Pre-Upgrade Preparation
Backup Verification:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | # Create pre-upgrade backup
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backups/pre-upgrade-${DATE}"
mkdir -p "${BACKUP_DIR}"
# Database backup
docker exec firefly-iii-application.mariadb mysqldump \
-u application -p'${DB_PASSWORD}' application \
> "${BACKUP_DIR}/database.sql"
# Storage backup
docker run --rm \
-v firefly-iii-application-application-storage-data:/source:ro \
-v "${BACKUP_DIR}":/backup \
alpine:latest \
tar czf /backup/storage.tar.gz -C /source .
# Configuration backup
cp .env "${BACKUP_DIR}/env.backup"
cp docker-compose.yml "${BACKUP_DIR}/compose.backup"
# Verify backup integrity
test -s "${BACKUP_DIR}/database.sql" || { echo "Database backup failed"; exit 1; }
test -s "${BACKUP_DIR}/storage.tar.gz" || { echo "Storage backup failed"; exit 1; }
|
Environment Validation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | # Check current version
docker exec firefly-iii-application.application \
php artisan --version
# Verify system health
curl -f http://localhost:8080/health || { echo "System unhealthy"; exit 1; }
# Check resource availability
df -h | grep -E "(/$|/var/lib/docker)" | awk '$5 > "80%" {print "Disk space warning: " $0}'
# Verify database connectivity
docker exec firefly-iii-application.mariadb \
mysql -u application -p'${DB_PASSWORD}' \
-e "SELECT COUNT(*) FROM transactions;" || { echo "Database check failed"; exit 1; }
|
Change Documentation:
| # Review changelog for breaking changes
curl -s https://api.github.com/repos/firefly-iii/firefly-iii/releases/latest | \
jq -r '.body' > changelog.md
# Check for configuration changes
echo "Review configuration requirements in changelog.md"
echo "Update .env file if necessary"
echo "Verify all required environment variables are set"
|
Upgrade Execution
Docker Compose Upgrade:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | # Set target version
TARGET_VERSION="6.1.18"
# Update docker-compose.yml
sed -i.backup "s/tag: \".*\"/tag: \"${TARGET_VERSION}\"/" docker-compose.yml
# Pull new images
docker compose pull
# Stop application (keep database running)
docker compose stop firefly-iii-application.application firefly-iii-application.nginx
# Start application with new version
docker compose up -d firefly-iii-application.application firefly-iii-application.nginx
# Wait for startup
echo "Waiting for application startup..."
timeout 300 bash -c 'until curl -f http://localhost:8080/health; do sleep 5; done'
|
Kubernetes Upgrade:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | # Update Helm values
TARGET_VERSION="6.1.18"
yq eval ".application.controllers.main.containers.app.image.tag = \"${TARGET_VERSION}\"" \
-i ops/helm/application-application/values.yaml
# Helm upgrade with rollback capability
helm upgrade firefly-iii-application \
ops/helm/application-application \
--namespace firefly-iii-application \
--wait \
--timeout 10m \
--atomic
# Verify deployment
kubectl get pods -n firefly-iii-application
kubectl logs -n firefly-iii-application deployment/firefly-iii-application
|
Database Migrations:
| # Migrations run automatically on startup, but can be run manually
docker exec firefly-iii-application.application \
php artisan migrate --force
# Check migration status
docker exec firefly-iii-application.application \
php artisan migrate:status
|
Rollback Procedures
Immediate Rollback (Docker Compose):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 | # Restore previous version
PREVIOUS_VERSION="6.1.17" # Set to known good version
# Stop current version
docker compose down
# Restore configuration
cp docker-compose.yml.backup docker-compose.yml
cp .env.backup .env
# Update to previous version
sed -i "s/tag: \".*\"/tag: \"${PREVIOUS_VERSION}\"/" docker-compose.yml
# Restore database if needed
if [ "${RESTORE_DATABASE}" = "true" ]; then
# Stop all services
docker compose down
# Restore database
cat "${BACKUP_DIR}/database.sql" | \
docker exec -i firefly-iii-application.mariadb \
mysql -u application -p'${DB_PASSWORD}' application
fi
# Start previous version
docker compose up -d
# Verify rollback
timeout 300 bash -c 'until curl -f http://localhost:8080/health; do sleep 5; done'
|
Kubernetes Rollback:
| # Helm rollback to previous release
helm rollback firefly-iii-application -n firefly-iii-application
# Or rollback to specific revision
helm history firefly-iii-application -n firefly-iii-application
helm rollback firefly-iii-application 3 -n firefly-iii-application
# Verify rollback
kubectl get pods -n firefly-iii-application
kubectl rollout status deployment/firefly-iii-application -n firefly-iii-application
|
Database Rollback:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | # Database rollback (destructive - use with caution)
# Only if database schema changes are incompatible
# Stop application
docker compose stop firefly-iii-application.application
# Restore database from backup
docker exec -i firefly-iii-application.mariadb \
mysql -u application -p'${DB_PASSWORD}' application \
< "${BACKUP_DIR}/database.sql"
# Restore storage if needed
docker run --rm \
-v firefly-iii-application-application-storage-data:/target \
-v "${BACKUP_DIR}":/backup:ro \
alpine:latest \
tar xzf /backup/storage.tar.gz -C /target
# Start application
docker compose start firefly-iii-application.application
|
Validation & Testing
Post-Upgrade Validation:
1
2
3
4
5
6
7
8
9
10
11
12
13 | # Health check validation
curl -f http://localhost:8080/health | jq '.status' | grep -q "healthy"
# Version verification
CURRENT_VERSION=$(docker exec firefly-iii-application.application php artisan --version | grep -o 'v[0-9.]*')
echo "Current version: ${CURRENT_VERSION}"
# Database integrity check
docker exec firefly-iii-application.application \
php artisan firefly-iii:verify
# Basic functionality test
curl -s http://localhost:8080/ | grep -q "Firefly III"
|
Functional Testing:
1
2
3
4
5
6
7
8
9
10
11
12 | # Test critical user journeys
echo "Testing login functionality..."
# Add automated login test here
echo "Testing transaction creation..."
# Add automated transaction test here
echo "Testing data export..."
# Add automated export test here
echo "Testing import functionality..."
# Add automated import test here
|
Performance Validation:
1
2
3
4
5
6
7
8
9
10
11
12 | # Response time check
RESPONSE_TIME=$(curl -o /dev/null -s -w '%{time_total}' http://localhost:8080/)
echo "Response time: ${RESPONSE_TIME}s"
# Memory usage check
MEMORY_USAGE=$(docker stats --no-stream --format "{.MemUsage}" firefly-iii-application.application)
echo "Memory usage: ${MEMORY_USAGE}"
# Database performance check
docker exec firefly-iii-application.mariadb \
mysql -u application -p'${DB_PASSWORD}' \
-e "SHOW GLOBAL STATUS LIKE 'Threads_connected';"
|
Upgrade Checklist
Pre-Upgrade:
- [ ] Review changelog for breaking changes
- [ ] Create database backup
- [ ] Create storage backup
- [ ] Verify system health
- [ ] Schedule maintenance window
- [ ] Notify users of potential downtime
During Upgrade:
- [ ] Update configuration files
- [ ] Pull new container images
- [ ] Stop application services
- [ ] Start services with new version
- [ ] Monitor startup logs
- [ ] Verify health checks pass
Post-Upgrade:
- [ ] Validate version upgrade
- [ ] Test critical functionality
- [ ] Check performance metrics
- [ ] Verify all services healthy
- [ ] Document any issues encountered
- [ ] Notify users of completion
Rollback (if needed):
- [ ] Stop current version
- [ ] Restore previous configuration
- [ ] Restore database if necessary
- [ ] Start previous version
- [ ] Verify rollback successful
- [ ] Document rollback reason
Emergency Procedures
Critical Upgrade Failure:
1. Immediately stop the application
2. Restore from backup
3. Start previous version
4. Verify system health
5. Notify stakeholders
6. Investigate root cause
Data Corruption Detection:
1. Stop application immediately
2. Do not restart until investigation complete
3. Restore from most recent clean backup
4. Document corruption details
5. Contact support if needed
Sources