add database backup and restore admin page
Some checks failed
deploy / deploy (push) Has been cancelled

- SQLCipher-encrypted backup creation via VACUUM INTO
- Backup history with auto-pruning (keeps last 5)
- Pre-restore automatic backup for safety
- Restore from history or uploaded file
- Stats display with table breakdown
- Download hook for client-side file download
- SECRET_KEY_DB config for encryption at rest

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
jamey
2026-03-13 13:33:29 +00:00
parent b0f8eea2bc
commit 09f55dfe67
10 changed files with 2183 additions and 1 deletions

View File

@@ -20,6 +20,15 @@ if System.get_env("PHX_SERVER") do
config :berrypod, BerrypodWeb.Endpoint, server: true
end
# SQLCipher encryption key — optional in dev/test, required in prod.
# x'...' tells SQLCipher to use the hex directly as the AES key,
# skipping PBKDF2 derivation (256k iterations per connection).
if config_env() != :prod do
if db_key = System.get_env("SECRET_KEY_DB") do
config :berrypod, Berrypod.Repo, key: "\"x'#{db_key}'\""
end
end
if config_env() == :prod do
database_path =
System.get_env("DATABASE_PATH") ||
@@ -28,8 +37,20 @@ if config_env() == :prod do
For example: /data/berrypod.db
"""
# Database encryption via SQLCipher (required in production)
db_key =
System.get_env("SECRET_KEY_DB") ||
raise """
environment variable SECRET_KEY_DB is missing.
This key encrypts the entire database at rest using SQLCipher.
You can generate one by calling: mix phx.gen.secret
"""
# x'...' tells SQLCipher to use the hex directly as the AES key,
# skipping PBKDF2 derivation (256k iterations per connection).
config :berrypod, Berrypod.Repo,
database: database_path,
key: "\"x'#{db_key}'\"",
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "5"),
journal_mode: :wal,
busy_timeout: 15_000,