kamal-backup
The easiest way to run scheduled backups for a Rails app deployed with Kamal. [](https://rubygems.org/gems/kamal-backup) [](https://github.com/crmne/kamal-backup/actions/workflows/ci.yml) [](https://github.com/crmne/kamal-backup/pkgs/container/kamal-backup) [](https://kamal-backup.dev) [](LICENSE)Backups for Rails apps deployed with Kamal should not become a separate ops project.
kamal-backup is one Kamal accessory that runs encrypted backups for your Rails database and file-backed Active Storage files on a schedule. It also gives you restore drills and redacted evidence for security reviews like CASA.
If you already deploy with Kamal, backups should feel like adding one more accessory.
Why Rails teams use it
Most self-hosted Rails apps need the same things:
- scheduled backups for PostgreSQL, MySQL/MariaDB, or SQLite
- file-backed Active Storage backups from mounted volumes
- a fast way to restore production data locally
- restore drills that do not touch the live production database
- evidence that says more than "the backup job is green"
kamal-backup packages that workflow into a small Ruby gem, a production accessory image, and a restic repository.
Quick start
Add the gem:
group :development do
gem "kamal-backup"
end
Generate the config file and accessory snippet:
bundle install
bundle exec kamal-backup init
Add the accessory to config/deploy.yml:
accessories:
backup:
image: ghcr.io/crmne/kamal-backup:latest
host: chatwithwork.com
files:
- config/kamal-backup.yml:/app/config/kamal-backup.yml:ro
env:
secret:
- PGPASSWORD
- RESTIC_PASSWORD
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
volumes:
- "chatwithwork_storage:/data/storage:ro"
- "chatwithwork_backup_state:/var/lib/kamal-backup"
Put the backup settings in config/kamal-backup.yml:
accessory: backup
app_name: chatwithwork
database_adapter: postgres
database_url: postgres://chatwithwork@chatwithwork-db:5432/chatwithwork_production
backup_paths:
- /data/storage
restic_repository: s3:https://s3.example.com/chatwithwork-backups
restic_init_if_missing: true
backup_schedule_seconds: 86400
Boot it. The container runs kamal-backup schedule by default:
bundle exec kamal-backup validate
bin/kamal accessory boot backup
bin/kamal accessory logs backup
Run the first backup and print evidence:
bundle exec kamal-backup -d production backup
bundle exec kamal-backup -d production list
bundle exec kamal-backup -d production evidence
What you get
- Scheduled backups: the accessory runs continuously and backs up on
backup_schedule_seconds. - Database and Active Storage coverage: database dumps plus file-backed Active Storage files from mounted volumes.
- Restic underneath: encrypted, deduplicated snapshots in S3-compatible storage, a restic REST server, or a filesystem repository.
- Local restores: pull production backups into your local Rails app when you need to inspect real data.
- Restore drills: restore into scratch production-side targets and record the result.
- Security review evidence:
kamal-backup evidenceprints redacted JSON with latest snapshots, checks, drills, retention, and tool versions.
Docs
Read the full documentation at kamal-backup.dev.
Start here:
License
MIT