396 lines
No EOL
9.9 KiB
Markdown
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
|
|
``` |