ComposeSync/Docs/safety-features.md

396 lines
No EOL
9.9 KiB
Markdown

# Safety Features
ComposeSync includes several safety features to protect your Docker stacks and ensure reliable operation.
## Overview
Safety features include:
- **Automatic rollback** on failed updates
- **Versioned backups** for easy recovery
- **Lock file protection** against concurrent updates
- **Override preservation** to maintain customizations
- **Error handling** with detailed logging
- **Dry-run mode** for testing configurations
## Automatic Rollback
When a Docker Compose update fails, ComposeSync automatically rolls back to the previous working version.
### How Rollback Works
1. **Pre-update backup** - Current configuration is saved before applying changes
2. **Update attempt** - New configuration is applied using `docker compose up -d`
3. **Failure detection** - If the update fails, the error is logged
4. **Automatic rollback** - Previous configuration is restored
5. **Notification** - Webhook notification is sent (if configured)
### Rollback Process
```bash
# Example rollback log
[2024-01-15 10:30:00] Processing stack: immich
[2024-01-15 10:30:01] Creating backup: compose-20240115103001.yml.bak
[2024-01-15 10:30:02] Applying new configuration...
[2024-01-15 10:30:03] ERROR: docker compose up -d failed
[2024-01-15 10:30:03] Rolling back to previous version
[2024-01-15 10:30:04] Rollback successful
[2024-01-15 10:30:04] Sending webhook notification
```
## Versioned Backups
ComposeSync maintains a history of your Docker Compose configurations for easy recovery.
### Backup Naming
Backups are named with timestamps or Git commit hashes:
```
/opt/composesync/stacks/immich/
├── docker-compose.yml # Current configuration
├── docker-compose.override.yml # Your customizations
├── compose-20240115103001.yml.bak # Timestamped backup
├── compose-20240115102001.yml.bak # Previous backup
└── compose-20240115101001.yml.bak # Older backup
```
### TOML Configuration
Configure backup retention in your TOML file:
```toml
# Global settings
[global]
UPDATE_INTERVAL_SECONDS = 3600
KEEP_VERSIONS = 10 # Keep 10 backup versions
DRY_RUN = false
# Stack configurations
[immich]
URL = "https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml"
PATH = "/opt/composesync/stacks/immich"
TOOL = "wget"
[dev-app]
URL = "https://github.com/user/dev-app.git"
PATH = "/opt/composesync/stacks/dev-app"
TOOL = "git"
GIT_SUBPATH = "docker/docker-compose.yml"
GIT_REF = "develop"
KEEP_VERSIONS = 5 # Keep fewer versions for dev
```
### Legacy .env Configuration
```env
# Global settings
UPDATE_INTERVAL_SECONDS=3600
KEEP_VERSIONS=10
DRY_RUN=false
# Stack configurations
STACKS=2
STACK_1_NAME=immich
STACK_1_URL=https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
STACK_1_PATH=/opt/composesync/stacks/immich
STACK_1_TOOL=wget
STACK_2_NAME=dev-app
STACK_2_URL=https://github.com/user/dev-app.git
STACK_2_PATH=/opt/composesync/stacks/dev-app
STACK_2_TOOL=git
STACK_2_GIT_SUBPATH=docker/docker-compose.yml
STACK_2_GIT_REF=develop
STACK_2_KEEP_VERSIONS=5
```
### Manual Rollback
To manually rollback to a previous version:
```bash
# List available backups
ls -la /opt/composesync/stacks/immich/compose-*.yml.bak
# Restore a specific backup
sudo cp /opt/composesync/stacks/immich/compose-20240115102001.yml.bak \
/opt/composesync/stacks/immich/docker-compose.yml
# Apply the rollback
cd /opt/composesync/stacks/immich
docker compose up -d
```
## Lock File Protection
ComposeSync uses lock files to prevent concurrent updates that could cause conflicts.
### Lock File Operation
1. **Lock acquisition** - Creates a lock file before starting updates
2. **Update process** - Performs the update while lock is held
3. **Lock release** - Removes the lock file when complete
4. **Timeout handling** - Automatically removes stale locks
### Lock File Location
```
/opt/composesync/
├── update-agent.sh
├── config.toml
├── .env
└── .lock # Global lock file
```
### Lock File Behavior
- **Single process** - Only one update process can run at a time
- **Automatic cleanup** - Stale locks are automatically removed
- **Error recovery** - Locks are released even if the process crashes
- **Timeout protection** - Long-running processes don't block indefinitely
## Override Preservation
Your `docker-compose.override.yml` files are always preserved during updates.
### Override File Structure
```
/opt/composesync/stacks/immich/
├── docker-compose.yml # Updated from remote source
├── docker-compose.override.yml # Your customizations (preserved)
├── compose-*.yml.bak # Backup versions
└── .git/ # Git repository (if using git)
```
### Override File Example
```yaml
# docker-compose.override.yml
version: '3.8'
services:
immich-server:
environment:
- DATABASE_URL=postgresql://user:pass@localhost:5432/immich
- REDIS_URL=redis://localhost:6379
volumes:
- /mnt/photos:/photos
- /mnt/backups:/backups
restart: unless-stopped
networks:
- immich-network
networks:
immich-network:
external: true
```
### How Overrides Work
1. **Download** - New `docker-compose.yml` is downloaded
2. **Preserve** - Your `docker-compose.override.yml` is kept unchanged
3. **Merge** - Docker Compose merges both files automatically
4. **Apply** - Combined configuration is applied
## Error Handling
ComposeSync includes comprehensive error handling and logging.
### Error Types
| Error Type | Description | Action Taken |
|------------|-------------|--------------|
| **Download failure** | Cannot download compose file | Skip stack, continue with others |
| **Parse error** | Invalid YAML in compose file | Skip stack, log error |
| **Docker failure** | `docker compose up -d` fails | Rollback to previous version |
| **Permission error** | Cannot write to stack directory | Skip stack, log error |
| **Network error** | Cannot reach remote source | Skip stack, retry later |
### Error Logging
```bash
# View error logs
sudo journalctl -u composesync | grep "ERROR"
# View recent errors
sudo journalctl -u composesync -n 100 | grep "ERROR"
# View specific stack errors
sudo journalctl -u composesync | grep "immich.*ERROR"
```
### Error Recovery
ComposeSync automatically recovers from most errors:
- **Temporary failures** - Retried on next update cycle
- **Permanent failures** - Logged and skipped until resolved
- **Partial failures** - Other stacks continue to update normally
## Dry-Run Mode
Test your configuration safely without applying changes.
### TOML Configuration
```toml
# Global dry-run mode
[global]
UPDATE_INTERVAL_SECONDS = 3600
KEEP_VERSIONS = 10
DRY_RUN = true # Enable dry-run mode
# Stack configurations
[immich]
URL = "https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml"
PATH = "/opt/composesync/stacks/immich"
TOOL = "wget"
```
### Per-Stack Dry-Run Mode
```toml
# Global settings
[global]
DRY_RUN = false # Default: apply changes
# Production stack (apply changes)
[immich]
URL = "https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml"
PATH = "/opt/composesync/stacks/immich"
TOOL = "wget"
# Development stack (dry-run only)
[dev-app]
URL = "https://github.com/user/dev-app.git"
PATH = "/opt/composesync/stacks/dev-app"
TOOL = "git"
GIT_SUBPATH = "docker/docker-compose.yml"
GIT_REF = "develop"
DRY_RUN = true # Override global setting
```
### Dry-Run Benefits
- **Safe testing** - No actual changes are applied
- **Configuration validation** - Verify URLs and settings work
- **Change preview** - See what would be updated
- **Webhook testing** - Test notifications without affecting stacks
## Best Practices
### 1. Use Appropriate Backup Retention
```toml
# Production stacks (keep more versions)
[production]
URL = "https://..."
PATH = "/opt/composesync/stacks/production"
TOOL = "wget"
KEEP_VERSIONS = 15
# Development stacks (keep fewer versions)
[development]
URL = "https://..."
PATH = "/opt/composesync/stacks/development"
TOOL = "git"
KEEP_VERSIONS = 5
```
### 2. Test with Dry-Run Mode
```toml
# Always test new configurations
[global]
DRY_RUN = true
[new-stack]
URL = "https://..."
PATH = "/opt/composesync/stacks/new-stack"
TOOL = "wget"
```
### 3. Monitor Error Logs
```bash
# Set up log monitoring
sudo journalctl -u composesync -f
# Check for errors regularly
sudo journalctl -u composesync --since "1 hour ago" | grep "ERROR"
```
### 4. Use Webhook Notifications
```toml
# Get notified of issues
[global]
NOTIFICATION_WEBHOOK_URL = "https://your-webhook-url.com/endpoint"
[immich]
URL = "https://..."
PATH = "/opt/composesync/stacks/immich"
TOOL = "wget"
```
### 5. Regular Backup Verification
```bash
# Verify backups are being created
ls -la /opt/composesync/stacks/*/compose-*.yml.bak
# Test backup restoration
sudo cp /opt/composesync/stacks/immich/compose-*.yml.bak /tmp/test.yml
docker compose -f /tmp/test.yml config
```
## Troubleshooting
### Rollback Not Working
```bash
# Check if backups exist
ls -la /opt/composesync/stacks/immich/compose-*.yml.bak
# Check rollback logs
sudo journalctl -u composesync | grep "rollback"
# Verify Docker Compose works
cd /opt/composesync/stacks/immich
docker compose config
```
### Lock File Issues
```bash
# Check for stale lock
ls -la /opt/composesync/.lock
# Remove stale lock (if needed)
sudo rm /opt/composesync/.lock
# Restart service
sudo systemctl restart composesync
```
### Override File Issues
```bash
# Check override file syntax
docker compose -f /opt/composesync/stacks/immich/docker-compose.yml \
-f /opt/composesync/stacks/immich/docker-compose.override.yml config
# Verify override file permissions
ls -la /opt/composesync/stacks/immich/docker-compose.override.yml
```
### Backup Cleanup Issues
```bash
# Check backup retention settings
grep "KEEP_VERSIONS" /opt/composesync/config.toml
# Manually clean old backups
find /opt/composesync/stacks -name "compose-*.yml.bak" -mtime +30 -delete
```