django-rclone
Django database and media backup management commands, powered by rclone.
django-rclone bridges Django's database layer with rclone's file transfer layer. You get native database dumps piped directly to any of rclone's 70+ supported cloud storage backends -- no temp files, no intermediate archives, no Python reimplementations of what rclone already does.
Why rclone instead of Django Storages?
django-dbbackup is a mature and well-regarded backup solution. It wraps Django Storages for upload, implements GPG encryption in Python, handles gzip compression, and parses filenames with regex to manage backups.
django-rclone takes a different approach: delegate everything that isn't Django-specific to rclone.
| Concern | django-dbbackup | django-rclone |
|---|---|---|
| Storage backends | Django Storages (S3, GCS, etc.) | rclone (70+ backends natively) |
| Encryption | GPG subprocess wrapper in Python | rclone crypt remote |
| Compression | gzip in Python | rclone compress remote or --compress flag |
| Media backup | Tar archive, then upload | rclone sync (incremental, no archiving) |
| Backup listing | Filename regex parsing | rclone lsjson (structured JSON) |
| Temp files | SpooledTemporaryFile |
None -- pipes directly via rclone rcat |
The result is significantly less code doing significantly less work. Storage abstraction, encryption, compression, and incremental sync are all rclone's problem -- django-rclone only owns what Django must own: database connectors, management commands, and signals.
Requirements
- Python 3.12+
- Django 5.2+
- rclone installed and configured
Installation
pip install django-rclone
Add to your INSTALLED_APPS:
INSTALLED_APPS = [
# ...
"django_rclone",
]
Configure your rclone remote (see rclone docs):
rclone config
Then point django-rclone at it:
DJANGO_RCLONE = {
"REMOTE": "myremote:backups",
}
Usage
Database backup and restore
# Backup the default database
python manage.py dbbackup
# Backup a specific database
python manage.py dbbackup --database analytics
# Backup and clean old backups beyond retention count
python manage.py dbbackup --clean
# Restore from the latest backup
python manage.py dbrestore
# Restore a specific backup
python manage.py dbrestore --input-path default-2024-01-15-120000.dump
# Non-interactive restore (for automation)
python manage.py dbrestore --noinput --input-path default-2024-01-15-120000.dump
Media backup and restore
# Sync MEDIA_ROOT to remote (incremental -- only changed files transfer)
python manage.py mediabackup
# Sync remote back to MEDIA_ROOT
python manage.py mediarestore
List backups
# List all database backups
python manage.py listbackups
# Filter by database
python manage.py listbackups --database default
# List media files on remote
python manage.py listbackups --media
Configuration
All settings live under the DJANGO_RCLONE dict in your Django settings:
DJANGO_RCLONE = {
# Required -- rclone remote and base path
"REMOTE": "myremote:backups",
# Optional -- rclone binary and config
"RCLONE_BINARY": "rclone", # Path to rclone binary
"RCLONE_CONFIG": None, # Path to rclone.conf (None uses default)
"RCLONE_FLAGS": [], # Extra flags for every rclone call
# Database backup settings
"DB_BACKUP_DIR": "db", # Subdirectory for DB backups
"DB_FILENAME_TEMPLATE": "{database}-{datetime}.{ext}", # Must start with {database}
"DB_DATE_FORMAT": "%Y-%m-%d-%H%M%S",
"DB_CLEANUP_KEEP": 10, # Keep N most recent backups per database
# Media backup settings
"MEDIA_BACKUP_DIR": "media", # Subdirectory for media backups
# Database connector overrides
"CONNECTORS": {}, # Per-database connector class overrides
"CONNECTOR_MAPPING": {}, # Engine-to-connector class overrides
}
Encryption and compression
django-rclone does not implement encryption or compression. Instead, configure these at the rclone level where they belong:
Encryption -- use a crypt remote:
rclone config create myremote-crypt crypt remote=myremote:backups password=your-password
Then set "REMOTE": "myremote-crypt:" in your Django settings.
Compression -- use a compress remote:
rclone config create myremote-compressed compress remote=myremote:backups
Or pass --compress-level via RCLONE_FLAGS.
See Storage Providers for provider-specific configuration notes (Cloudflare R2, etc.).
Supported databases
| Database | Connector | Dump tool | Format |
|---|---|---|---|
| PostgreSQL | PgDumpConnector |
pg_dump / pg_restore |
Custom (binary) |
| PostGIS | PgDumpGisConnector |
pg_dump / pg_restore |
Custom (binary) |
| MySQL / MariaDB | MysqlDumpConnector |
mysqldump / mysql |
SQL text |
| SQLite | SqliteConnector |
sqlite3 .dump |
SQL text |
| MongoDB | MongoDumpConnector |
mongodump / mongorestore |
Archive (binary) |
GIS backends (postgis, spatialite, gis/mysql) and django-prometheus wrappers are also mapped automatically. See connectors documentation for the full engine mapping table.
Signals
django-rclone sends Django signals before and after each operation:
from django_rclone.signals import pre_db_backup, post_db_backup
@receiver(post_db_backup)
def notify_on_backup(sender, database, path, **kwargs):
logger.info("Database %s backed up to %s", database, path)
Available signals: pre_db_backup, post_db_backup, pre_db_restore, post_db_restore, pre_media_backup, post_media_backup, pre_media_restore, post_media_restore.
Architecture
Management Commands (dbbackup, dbrestore, mediabackup, mediarestore, listbackups)
| |
DB Connectors rclone.py
(pg, mysql, sqlite, (subprocess wrapper)
mongodb)
| |
Database binary rclone binary
(70+ storage backends)
Database dumps stream directly from the dump process into rclone rcat via Unix pipes. No intermediate files are written. Restores work in reverse: rclone cat streams into the database restore process. Subprocess finalization is centralized and deadlock-safe (pipe draining + stderr collection).
Media backups use rclone sync, which is incremental by default -- only changed files are transferred.
Development
Contributions are welcome. This project enforces 100% test coverage -- all new code must be fully covered by tests. The CI pipeline will fail if coverage drops below 100%.
CI also includes subprocess guardrail tests to prevent wait()-based pipe deadlocks and to keep raw Popen(...) usage confined to the wrapper modules.
uv sync # Install runtime + dev deps (tests/lint/type/docs)
uv run pytest --cov --cov-branch # Unit tests (integration excluded by default)
uv sync --group integration # Install DB integration test dependencies
uv run pytest tests/integration -m integration -q # Integration tests (requires tools/services)
uv run ruff check . # Lint
uv run ruff format --check . # Check formatting
uv run ty check # Type check
uv run mkdocs build --strict # Build docs
For full integration setup details (Docker services, required binaries, env vars), see docs/testing.md.
License
MIT
Release files for django-rclone 0.4.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 | |
|---|---|---|---|
| django_rclone-0.4.0.tar.gz | 91.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_rclone-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 115.7 kB
Release files / django_rclone-0.4.0.tar.gz
| Download URL | django_rclone-0.4.0.tar.gz |
|---|---|
| Size | 91.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
36536a80466970ecd680c8963a20a5ccb2859227dda8269d46d02f334c844819
|
|
BLAKE2b-256 checksum How to use checksums |
be631894501aecb8736b204a6cc80335d8288dcb81cb424f734dc6494bf35a90
|
| 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 Feb 18, 2026.
Transparency logRelease files / django_rclone-0.4.0-py3-none-any.whl
| Download URL | django_rclone-0.4.0-py3-none-any.whl |
|---|---|
| Size | 24.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7d12a51c1ce960fe10a38ab1a185153cbfdaab5ae846bcd57bd79b6808d7dc9e
|
|
BLAKE2b-256 checksum How to use checksums |
97151da17b2d33bf4ca1a84edd30789c5a1e5503d113652e51703ac20d3a54a2
|
| 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 Feb 18, 2026.
Transparency log