Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ A script to automatically back up all databases running under docker on a host,
- [pgautoupgrade](https://github.com/pgautoupgrade/docker-pgautoupgrade))
- Redis

### Custom Backup Providers

You can extend the existing backup providers with additional container patterns by setting environment variables:

```
CUSTOM_BACKUP_PROVIDER_POSTGRES_PATTERNS=immich-app/postgres,my-custom-postgres
CUSTOM_BACKUP_PROVIDER_MYSQL_PATTERNS=my-custom-mysql,another-mysql-container
CUSTOM_BACKUP_PROVIDER_REDIS_PATTERNS=my-custom-redis
```

Each variable should contain a comma-separated list of container patterns to match.

## Installation

This container requires access to the docker socket. This can be done either by mounting `/var/lib/docker.sock`, or using a HTTP proxy to provide it through `$DOCKER_HOST`.
Expand Down Expand Up @@ -55,6 +67,9 @@ services:
environment:
- SUCCESS_HOOK_URL=https://hc-ping.com/1234
- INCLUDE_LOGS=true
# Custom backup provider patterns
- CUSTOM_BACKUP_PROVIDER_POSTGRES_PATTERNS=immich-app/postgres,custom-postgres
- CUSTOM_BACKUP_PROVIDER_MYSQL_PATTERNS=my-custom-mysql
```

### Oneshot
Expand Down
33 changes: 33 additions & 0 deletions db-auto-backup.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,39 @@ def backup_redis(container: Container) -> str:
),
]

# Extend backup providers with custom patterns from environment variables
# Format: CUSTOM_BACKUP_PROVIDER_<provider_name>_PATTERNS=pattern1,pattern2,...
for env_var, value in os.environ.items():
if env_var.startswith("CUSTOM_BACKUP_PROVIDER_") and env_var.endswith("_PATTERNS"):
provider_name = (
env_var.replace("CUSTOM_BACKUP_PROVIDER_", "")
.replace("_PATTERNS", "")
.lower()
)
custom_patterns = [
pattern.strip() for pattern in value.split(",") if pattern.strip()
]

# Find the provider and extend its patterns
for provider in BACKUP_PROVIDERS:
if provider.name.lower() == provider_name:
# Create a new BackupProvider with extended patterns
index = BACKUP_PROVIDERS.index(provider)
BACKUP_PROVIDERS[index] = BackupProvider(
name=provider.name,
patterns=provider.patterns + custom_patterns,
backup_method=provider.backup_method,
file_extension=provider.file_extension,
)
print(
f"Extended {provider.name} backup provider with patterns: {', '.join(custom_patterns)}"
)
break
else:
print(
f"Warning: Custom backup provider {provider_name} not found, skipping patterns: {', '.join(custom_patterns)}"
)


BACKUP_DIR = Path(os.environ.get("BACKUP_DIR", "/var/backups"))
SCHEDULE = os.environ.get("SCHEDULE", "0 0 * * *")
Expand Down
57 changes: 57 additions & 0 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,60 @@ def test_get_backup_provider(container_name: str, name: str) -> None:

assert provider is not None
assert provider.name == name


def test_custom_backup_provider_patterns(monkeypatch: Any) -> None:
# Save original backup providers
original_providers = db_auto_backup.BACKUP_PROVIDERS.copy()

try:
# Set custom patterns environment variable
monkeypatch.setenv(
"CUSTOM_BACKUP_PROVIDER_POSTGRES_PATTERNS",
"immich-app/postgres,custom-postgres",
)

# Create a copy of the original providers
test_providers = original_providers.copy()
db_auto_backup.BACKUP_PROVIDERS = test_providers

# Run the code that processes environment variables
for env_var, value in {
"CUSTOM_BACKUP_PROVIDER_POSTGRES_PATTERNS": "immich-app/postgres,custom-postgres"
}.items():
if env_var.startswith("CUSTOM_BACKUP_PROVIDER_") and env_var.endswith(
"_PATTERNS"
):
provider_name = (
env_var.replace("CUSTOM_BACKUP_PROVIDER_", "")
.replace("_PATTERNS", "")
.lower()
)
custom_patterns = [
pattern.strip() for pattern in value.split(",") if pattern.strip()
]

for provider in db_auto_backup.BACKUP_PROVIDERS:
if provider.name.lower() == provider_name:
index = db_auto_backup.BACKUP_PROVIDERS.index(provider)
db_auto_backup.BACKUP_PROVIDERS[
index
] = db_auto_backup.BackupProvider(
name=provider.name,
patterns=provider.patterns + custom_patterns,
backup_method=provider.backup_method,
file_extension=provider.file_extension,
)
break

# Test with the new custom pattern
provider = db_auto_backup.get_backup_provider(["immich-app/postgres"])
assert provider is not None
assert provider.name == "postgres"

provider = db_auto_backup.get_backup_provider(["custom-postgres"])
assert provider is not None
assert provider.name == "postgres"
finally:
# Restore original backup providers
db_auto_backup.BACKUP_PROVIDERS = original_providers