No description
Find a file
2026-03-31 22:21:46 -06:00
.claude lint fix 2026-03-31 21:19:57 -06:00
.github/workflows updates 2026-03-31 22:21:46 -06:00
cmd/doomsday lint fix 2026-03-31 21:19:57 -06:00
internal lint fix 2026-03-31 21:19:57 -06:00
.gitignore Initial commit 2026-03-22 00:17:46 +00:00
.goreleaser.yaml Initial commit 2026-03-22 00:17:46 +00:00
CLAUDE.md Initial commit 2026-03-22 00:17:46 +00:00
Dockerfile Initial commit 2026-03-22 00:17:46 +00:00
go.mod updates 2026-03-31 21:50:20 -06:00
go.sum updates 2026-03-31 21:50:20 -06:00
LICENSE Initial commit 2026-03-22 00:17:46 +00:00
logo.png Initial commit 2026-03-22 00:17:46 +00:00
mise.toml lint fix 2026-03-31 21:19:57 -06:00
README.md fixes 2026-03-21 19:00:27 -06:00
spec.md Initial commit 2026-03-22 00:17:46 +00:00

Doomsday

Doomsday

Backup for the End of the World

CI Release Go Report Card Go Version

An all-in-one, end-to-end encrypted backup solution.
Single binary. Zero dependencies. Beautiful TUI. Can never lose data.


Features

  • End-to-end encryption -- AES-256-GCM with HKDF-derived sub-keys. The server never sees plaintext.
  • Content-defined chunking -- FastCDC deduplication means only changed data moves over the wire after the first backup.
  • Multiple backends -- Local filesystem, SFTP, and S3-compatible storage (Backblaze B2, MinIO, Wasabi, Cloudflare R2).
  • Single binary -- CGO_ENABLED=0 Go binary. Runs on Linux, macOS, and Windows. No runtime dependencies.
  • 24-word recovery phrase -- BIP39 mnemonic. 256 bits of entropy. If you lose this, your data is gone forever.
  • Built-in TUI -- Interactive terminal UI for browsing snapshots, restoring files, and monitoring backup health.
  • SFTP server mode -- Run Doomsday as a backup target with per-user quotas and append-only mode.
  • Flexible retention -- Keep last N, hourly, daily, weekly, monthly, yearly policies per backup config.
  • Notifications -- Command execution, webhooks, or email on backup failure. Escalation if no successful backup in N days.
  • Cron mode -- doomsday client cron install generates systemd timers or launchd plists. No crontab editing.
  • Self-updating -- doomsday update pulls the latest signed release.
  • Whimsy -- Backup software doesn't have to be boring. (Disable with whimsy = false if you hate fun.)

Installation

Homebrew

brew install jclement/tap/doomsday

Go

go install github.com/jclement/doomsday/cmd/doomsday@latest

Docker

docker pull ghcr.io/jclement/doomsday:latest

Binary releases

Grab a pre-built binary from Releases. All checksums are signed with cosign.

Quick Start

1. Initialize

Generate your master encryption key. Write down the 24-word recovery phrase. Guard it with your life.

doomsday client init

2. Configure

Create ~/.config/doomsday/client.yaml:

# ~/.config/doomsday/client.yaml

key: env:DOOMSDAY_PASSWORD   # or a literal passphrase

sources:
  - path: ~/Documents
  - path: ~/Projects
    exclude: [node_modules, .git, vendor]

exclude:
  - .cache
  - "*.tmp"
  - .Trash

schedule: hourly

retention:
  keep_last: 5
  keep_hourly: 24
  keep_daily: 7
  keep_weekly: 4
  keep_monthly: 12
  keep_yearly: -1

destinations:
  - name: nas
    type: sftp
    host: nas.local
    port: 2222
    user: backup
    ssh_key: "base64-ed25519-key"
    host_key: "SHA256:xxxx"
    schedule: 4h
    retention:
      keep_daily: 30

  - name: b2
    type: s3
    endpoint: s3.us-west-004.backblazeb2.com
    bucket: my-doomsday-backups
    key_id: env:DOOMSDAY_B2_KEY_ID
    secret_key: env:DOOMSDAY_B2_APP_KEY

settings:
  compression: zstd
  compression_level: 3

3. Backup

# Run a backup
doomsday client backup

# Verbose output
doomsday client backup --verbose

4. Browse & Restore

# List snapshots
doomsday client snapshots

# List files in a snapshot
doomsday client ls latest

# Find a file across snapshots
doomsday client find "taxes/2025*.pdf"

# Diff two snapshots
doomsday client diff abc123 def456

# Restore everything from the latest snapshot
doomsday client restore latest --target /tmp/restore

# Restore a specific path
doomsday client restore latest:Documents/taxes --target /tmp/taxes

5. Maintenance

# Verify backup integrity
doomsday client check

# Prune old snapshots per retention policy
doomsday client prune

# Show backup status and health
doomsday client status

Secret Management

No secret ever needs to be stored in plaintext. Doomsday supports three resolution prefixes for any secret value in client.yaml:

Prefix Example Description
env: env:DOOMSDAY_B2_KEY Read from environment variable
file: file:/run/secrets/key Read from file (Docker/K8s secrets)
cmd: cmd:op read "op://vault/item/field" Execute a command (1Password, pass, Keychain)

Works great with secret managers:

# 1Password
op run --env-file=.env.doomsday -- doomsday client backup

# AWS Vault
aws-vault exec backup-role -- doomsday client backup

# Just export
export DOOMSDAY_PASSWORD="correct horse battery staple"
doomsday client restore latest --target /tmp/restore

Cron Mode

# Install a systemd timer / launchd plist
doomsday client cron install

# Run scheduled backups (used by the installed timer)
doomsday client cron

Configure notifications so you know when things go wrong:

notifications:
  policy: on_failure
  targets:
    - type: command
      command: "ntfy pub --title 'Doomsday backup failed' doomsday-alerts"

Interactive TUI

Browse snapshots interactively:

doomsday client browse

Browse snapshots, restore files, monitor backup health, and manage keys -- all from an interactive terminal interface built with Bubble Tea.

Server Mode

Run Doomsday as an SFTP backup target for other machines:

doomsday server serve

JSON Output

Every command supports --json for scripting and automation:

doomsday client snapshots --json | jq '.snapshots[0].id'
doomsday client backup --json
doomsday client status --json

Security

  • AES-256-GCM encryption with HKDF-derived per-blob sub-keys
  • HMAC-SHA256 content-addressed blob IDs (keyed -- no oracle attacks)
  • scrypt key derivation (N=2^17, r=8, p=1) for password-based access
  • BIP39 24-word recovery phrase (256 bits of entropy)
  • All releases signed with cosign
  • CI runs govulncheck on every push

License

MIT


Vibe coded with Claude