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
Metadata
Release files for duplicaid 4.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| duplicaid-4.3.0.tar.gz | 78.9 kB | With provenance | Details for duplicaid-4.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| duplicaid-4.3.0-py3-none-any.whl | Python 3 | none | any | Details for duplicaid-4.3.0-py3-none-any.whl |
Total release size: 96.5 kB
Release files / duplicaid-4.3.0.tar.gz
| Download URL | duplicaid-4.3.0.tar.gz |
|---|---|
| Size | 78.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
49a8faced7678a3b5538985ff36b6a5469bd1099892d1bda4af02c54b074fba8
|
|
BLAKE2b-256 checksum How to use checksums |
b9509c15672f47e23921e2ab6e4e447ba7dfbe535d31128546539fc913db8ecb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 23, 2025.
Transparency logRelease files / duplicaid-4.3.0-py3-none-any.whl
| Download URL | duplicaid-4.3.0-py3-none-any.whl |
|---|---|
| Size | 17.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9a786aba1aa7b3d514704b8dedbc5511fdaaf199864ea5df0583d52033ddeeb5
|
|
BLAKE2b-256 checksum How to use checksums |
63b2411eb1a8b69f0d3501a5582ccac66d209540b234ebb4d597fde1072464d2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 23, 2025.
Transparency logSecurity for duplicaid 4.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for duplicaid-4.3.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 23, 2025.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.