CLI tool for managing PostgreSQL backups via WAL-G and logical dumps with configurable database connections
Project description
DuplicAid
DuplicAid is a CLI tool for managing PostgreSQL backups using SQL dumps. It provides a unified interface for creating, listing, and restoring backups from PostgreSQL instances running in Docker containers.
The tool supports both local and remote execution modes.
⚠️ The package depends on tiredofit/docker-db-backup:4.1.21 for backup operations.
Features
- SQL Dumps: Create and restore database backups using pg_dump/pg_restore
- S3 Integration: Store and retrieve backups from S3-compatible storage
- Dual Execution Modes: Manage backups locally or on remote servers via SSH
Installation
Install duplicaid using uv:
# Install from PyPI
uv add duplicaid
# Or install from source
git clone <repository-url>
cd duplicaid
uv sync --extra dev
Configuration
Duplicaid stores configuration in .duplicaid.yml in your current working directory by default. You can specify a different location using the --config flag.
Execution Modes
Remote Mode (default):
- Manages PostgreSQL containers on a remote server via SSH
- Requires SSH key authentication
- All Docker commands executed on remote server
Local Mode:
- Manages PostgreSQL containers on the local machine
- No SSH connection required
- Docker commands executed locally
Setup
Initialize configuration interactively:
duplicaid config init
Configuration Options
- Execution Mode:
remoteorlocal - Remote Server (remote mode only): SSH connection details (host, user, port, key path)
- Container Names: PostgreSQL and backup container names
- PostgreSQL Credentials: Database user and password
- Paths: Docker Compose file location
Example Configurations
Remote Mode:
execution_mode: remote
remote:
host: your-server.example.com
user: root
port: 22
ssh_key_path: /home/user/.ssh/id_rsa
containers:
postgres: postgres
backup: db-backup
postgres:
user: postgres
password: your_secure_password
host: postgres
s3:
endpoint: https://s3.amazonaws.com
bucket: my-backups
path: postgres/backups
# access_key and secret_key can be set here or via env vars:
# AWS_ACCESS_KEY_ID / S3_ACCESS_KEY
# AWS_SECRET_ACCESS_KEY / S3_SECRET_KEY
paths:
docker_compose: /home/user/postgres/docker-compose.yml
databases:
- myapp
- analytics
Local Mode:
execution_mode: local
containers:
postgres: postgres
backup: db-backup
postgres:
user: postgres
password: your_secure_password
host: postgres
s3:
endpoint: http://localhost:9000
bucket: my-backups
path: postgres/backups
paths:
docker_compose: /home/user/postgres/docker-compose.yml
S3 Credentials:
S3 credentials can be configured in two ways:
-
In config file (less secure):
s3: access_key: YOUR_ACCESS_KEY secret_key: YOUR_SECRET_KEY
-
Via environment variables (recommended):
export AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY export AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY # or export S3_ACCESS_KEY=YOUR_ACCESS_KEY export S3_SECRET_KEY=YOUR_SECRET_KEY
Quick Start
-
Initialize Configuration:
duplicaid config init
-
Check Status:
duplicaid status -
Create a Backup:
duplicaid backup create
-
List Backups:
duplicaid list backups
-
Restore a Backup:
duplicaid restore mydb backup_file.sql.bz2
Backup Operations
Creating Backups
- Storage: S3-compatible storage (compressed with bzip2)
- Scope: All configured databases backed up automatically
- Format:
pgsql_hostname_database_YYYYMMDD-HHMMSS.sql.bz2
Listing Backups
Backups can be listed from:
- S3-compatible storage (if configured)
- Local backup directory (fallback)
Restoring Backups
- Source: Automatically downloads from S3 if not found locally
- Scope: Database-specific restoration
- Compatibility: Works across PostgreSQL versions
Requirements
Common Requirements
- Python 3.12+
- Docker and Docker Compose
- PostgreSQL container
- tiredofit/db-backup container for backup operations
Remote Mode Additional Requirements
- SSH access to remote server
- SSH key authentication configured
Local Mode Additional Requirements
- Docker daemon running locally
- Access to local Docker socket
Development
Setup
-
Clone and setup:
git clone <repository-url> cd duplicaid uv sync --extra dev
-
Install pre-commit hooks:
uv run pre-commit install
-
Run tests:
uv run pytest
Project Structure
duplicaid/
├── pyproject.toml # Project configuration and dependencies
├── README.md # This file
├── src/
│ └── duplicaid/ # Main package
│ ├── __init__.py
│ ├── cli.py # CLI interface
│ ├── config.py # Configuration management
│ ├── backup.py # Backup operations
│ ├── ssh.py # SSH connectivity
│ ├── executor.py # Command execution
│ ├── discovery.py # Database discovery
│ └── local.py # Local operations
└── tests/ # Test suite
├── conftest.py
├── test_cli.py
├── test_config.py
├── test_integration.py
└── test_local_executor.py
Testing
The test suite includes:
- Unit tests: Test individual components
- Integration tests: Test component interactions
- CLI tests: Test command-line interface
Run specific test types:
# All tests
uv run pytest
# Unit tests only
uv run pytest -k "not integration"
# Integration tests only
uv run pytest -m integration
# With coverage
uv run pytest --cov=duplicaid
Development Workflow
This project uses automated releases with semantic commits.
Quick Start
# 1. Create feature branch
git checkout -b feat/new-feature
# 2. Push and create PR
git push origin feat/new-feature
# 3. Merge PR → Auto-release to PyPI
Semantic Commits
git commit -m "fix: resolve timeout" # → patch release
git commit -m "feat: add encryption" # → minor release
git commit -m "feat!: redesign API" # → major release
Automation
- PRs: Auto-test, lint, format
- Main branch: Auto-version, auto-publish to PyPI
- Pre-commit: Enforce quality and commit format
Building and Publishing
# Manual build (for testing)
uv build
# Automated publishing (via GitHub Actions)
# → Happens automatically on main branch pushes
# → No manual PyPI uploads needed
# Emergency manual publish (not recommended)
uv publish
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file duplicaid-4.2.2.tar.gz.
File metadata
- Download URL: duplicaid-4.2.2.tar.gz
- Upload date:
- Size: 78.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3179bece45bc8965fb65b51083a6c56b1bd22672defe988a61622a758ff10f74
|
|
| MD5 |
e282b4f216ca5cec917d3bedfa3bc63e
|
|
| BLAKE2b-256 |
2edea869b5da48fb216f328429076a5c18900fe92727581e3cff8b95d05b1fc2
|
Provenance
The following attestation bundles were made for duplicaid-4.2.2.tar.gz:
Publisher:
release.yml on CorrelAid/duplicaid
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
duplicaid-4.2.2.tar.gz -
Subject digest:
3179bece45bc8965fb65b51083a6c56b1bd22672defe988a61622a758ff10f74 - Sigstore transparency entry: 776274523
- Sigstore integration time:
-
Permalink:
CorrelAid/duplicaid@4c9ad277653b77afea3732763adfbba30f7fdd09 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/CorrelAid
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4c9ad277653b77afea3732763adfbba30f7fdd09 -
Trigger Event:
push
-
Statement type:
File details
Details for the file duplicaid-4.2.2-py3-none-any.whl.
File metadata
- Download URL: duplicaid-4.2.2-py3-none-any.whl
- Upload date:
- Size: 16.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
feb9787ea28b4cee0a390162af49e416f8352b4436d0ed06ef6e426ec59e8e83
|
|
| MD5 |
552496014d162e685ed323ce5a5870b8
|
|
| BLAKE2b-256 |
795d66137267076d2eeef9396d6b97a675a132bbadeb8a4c8f35d0e5b2ea5d9e
|
Provenance
The following attestation bundles were made for duplicaid-4.2.2-py3-none-any.whl:
Publisher:
release.yml on CorrelAid/duplicaid
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
duplicaid-4.2.2-py3-none-any.whl -
Subject digest:
feb9787ea28b4cee0a390162af49e416f8352b4436d0ed06ef6e426ec59e8e83 - Sigstore transparency entry: 776274526
- Sigstore integration time:
-
Permalink:
CorrelAid/duplicaid@4c9ad277653b77afea3732763adfbba30f7fdd09 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/CorrelAid
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4c9ad277653b77afea3732763adfbba30f7fdd09 -
Trigger Event:
push
-
Statement type: