Berth

SQLite

If your app wants a SQLite file rather than a database server, give it one:

berth sqlite:add myapp

The app now has DATABASE_URL=sqlite:////data/sqlite/app.db, and SQLITE_PATH=/data/sqlite/app.db for libraries that want a plain path. If DATABASE_URL is already taken, pick another name with --as SQLITE_URL.

berth sqlite:shell myapp                        # sqlite3, inside the app
berth sqlite:shell myapp "select count(*) from notes"
berth sqlite:backup myapp                       # → ~/.berth/backups/sqlite/myapp/<time>.db
berth sqlite:restore myapp ~/.berth/backups/sqlite/myapp/20261028-030000.db
berth sqlite:list
berth sqlite:remove myapp                       # the data stays unless you add --delete-data

The file lives on a disk image that only one container can attach at a time. That matters because every Berth container is its own little VM, and SQLite's locks don't reach from one VM into another. Two containers sharing a SQLite file in an ordinary folder can both write at once and corrupt it. So an app with SQLite runs one container at a time:

  • Deploys stop the old version before starting the new one. Visitors wait a few seconds rather than getting an error. If the new version doesn't come up, the old one starts again.
  • Scheduled jobs and berth run happen inside the running app, not in a new container.
  • Workers can use the database too: they run inside the app's container, like every app's workers.

It's backed up every night along with Postgres, and before every release command. Each backup is one ordinary SQLite file in ~/.berth/backups/sqlite/, checked on the Mac before it's kept. Backups happen while the app keeps running, as long as its image has sqlite3 or Python (most do). If it has neither, the nightly backup stops the app for a few seconds instead, and sqlite:backup asks you to add --stop.

Dev versions and previews get their own empty database, and your release command sets it up.

Edit this page on GitHub (it's a section of the README)