Writing, 30 Sept 2026, 4 min read

Archon: encrypted database backups as a Docker sidecar

Archon adds automatic, encrypted, checksum-verified backups for Postgres, MongoDB, MySQL and SQLite to any Docker stack, with no code changes.

Every team rebuilds database backups, and most rebuild them badly: a pg_dump cron job, no encryption, no checksum, and nobody finds out it was broken until the day it is needed. I built Archon, an open-source Docker sidecar, so any project gets encrypted, verified database backups by adding one block to docker-compose.yml.

The problem

Here is how backups usually look on a small team. Someone writes a cron job that runs pg_dump every night and writes the file to the same server. Nobody encrypts it. Nobody checks that last night’s file is readable. Old dumps pile up until the disk fills. When you finally need a restore, it means SSH, guesswork and a lot of stress.

Then the next project does it again, slightly differently, in another language.

Managed databases like RDS and Atlas solve part of this, but they lock you to one provider, you don’t hold the encryption key, and they don’t help with the SQLite file or the MongoDB container running next to your app.

What it does

Archon runs beside your app as one container and reads one YAML file.

  • Backs up on a schedule. Each database gets its own readable schedule, like daily at 14:00 Asia/Kolkata.
  • Encrypts every file. AES-256-CBC, with a key that lives only in memory and never touches disk.
  • Proves the file is intact. Every backup gets a SHA-256 checksum saved next to it.
  • Stores it where you want. Local disk, Amazon S3 or Azure Blob.
  • Cleans up after itself. Hourly, daily, weekly and monthly retention limits are enforced, so the disk never fills.
  • Restores safely. One API call, and the file is verified before anything touches your database.

It supports PostgreSQL, MongoDB, MySQL and SQLite, each through its own native tool. Nothing changes in your code: no SDK, no hook, no vendor lock-in.

How it works

Every backup goes through the same five steps, in the same order:

  1. Dump: run the database’s own tool, such as pg_dump, in a subprocess.
  2. Encrypt: seal the dump with AES-256-CBC.
  3. Checksum: write a SHA-256 fingerprint as a .sha256 file beside it.
  4. Store: upload both to local disk, S3 or Azure.
  5. Retain: delete copies beyond your retention limits.
flowchart LR
    subgraph Backup
        D["Dump"] --> E["Encrypt, AES-256"] --> C["Checksum, SHA-256"] --> S["Store: disk, S3, Azure"] --> R["Prune old copies"]
    end
    subgraph Restore
        RD["Read file + checksum"] --> V{"Checksum matches?"}
        V -->|"yes"| DE["Decrypt"] --> RS["Drop, recreate, restore"]
        V -->|"no"| X["Abort. Database untouched"]
    end

Restores run the reverse, with a gate in the middle. Archon reads the file, verifies the checksum first, and only then decrypts and restores. If the checksum doesn’t match, the restore stops and your database is untouched:

$ curl -X POST :8765/restore -d '{...,"confirm":true}'
integrity_failed  sha256 mismatch
  restore aborted, database untouched

A few rules never change, by design. A restore without "confirm": true is refused, so there is no silent restore. Requests return 202 with a job ID instead of blocking, and a second backup of the same database queues behind the first instead of running in parallel. Events stream live over /logs/stream and go out as HMAC-signed webhooks.

Archon can also restore single rows. You open a session on any backup, browse its tables, pick rows, let it resolve foreign keys, and apply only those rows back.

Try it

Generate two keys and put them in .env:

ARCHON_API_KEY=$(openssl rand -hex 32)
ENCRYPTION_KEY=$(openssl rand -base64 32)

Add Archon to your existing docker-compose.yml:

archon:
  image: archon:latest
  volumes:
    - ./archon.config.yaml:/app/config.yaml
    - ./backups:/app/backups
  ports:
    - "8765:8765"
  env_file: .env

Then trigger a backup:

curl -X POST http://localhost:8765/backup \
  -H "X-API-Key: $ARCHON_API_KEY" \
  -d '{"database": "primary_postgres"}'

Keep the encryption key safe. Without it, your backups cannot be decrypted.

What can go wrong, and what Archon does about it

Backups fail quietly, so Archon is built around the failures instead of the happy path.

A backup file gets corrupted or tampered with. The checksum is checked before decryption and before any write, so a bad file is refused, not restored.

Two backups of the same database start at once. The second one queues. It is never run in parallel and never dropped.

Someone restores the wrong thing by accident. Restores require an explicit confirm: true, and every restore is logged.

The disk fills up with old dumps. Retention runs after every backup, not as a separate job you might forget.

What’s next

Version 1 deliberately leaves out a few things: Slack or email alerts (webhooks cover events for now), point-in-time recovery, per-tenant backups, and job history beyond 24 hours. Those are the next candidates.

The code is on GitHub, MIT licensed, and the full documentation covers the API, configuration and comparisons. See my other work, or read how I built Sable, a shell that asks before it runs anything.

#docker#databases#backups#open-source

Comments

All writing RSS Reply by email