Backups
LCM backs up its own state into a passphrase-encrypted, portable archive. A backup contains everything that makes up an instance - it can be fully restored on a fresh instance.
What’s in the archive
Section titled “What’s in the archive”An .lcmbak (ZIP with AES-256-GCM / scrypt key derivation) bundles:
- the database snapshot (consistent SQLite snapshot),
- the master key (
lcm.key) - without it the at-rest encrypted fields would be unreadable, - the configuration (
config.json), - the TLS certificate.

Create a backup now
Section titled “Create a backup now”Under Settings → Backups, “Create backup now” immediately produces an
archive; the passphrase is prompted for. LCM takes a consistent snapshot of
the database (VACUUM INTO) for this - so a backup can be created while
running.
Automatic backups
Section titled “Automatic backups”For automatic backups to run, exactly two things are required - both are shown directly on the Settings → Backups page:
- “Automatic backups enabled” is switched on (default: on, every 24 hours).
- The passphrase is set as an environment variable -
LCM_BACKUP_PASSPHRASEfor the LCM service. An unattended backup cannot prompt for it; without it, every scheduled backup fails (visible as a failed “System-Backup” job on the Jobs page).
Whether the passphrase is set is shown on the Backups page as a badge
(“Passphrase set” / “Passphrase missing”); if it is missing while
automatic backups are enabled, a prominent warning with instructions appears
as well. This is how to set it - as a systemd drop-in
(/etc/systemd/system/lcm.service.d/backup.conf):
[Service]Environment=LCM_BACKUP_PASSPHRASE=a-long-secretthen:
systemctl daemon-reload && systemctl restart lcmOr in Docker Compose:
services: lcm: environment: LCM_BACKUP_PASSPHRASE: a-long-secretFurther settings:
- Interval (hours) and retention (count) - older backups are cleaned up automatically.
- Time of day - anchors the schedule at a fixed time (server time). If the interval divides the day (1, 2, 3, 4, 6, 8, 12 or 24 hours), backups run at fixed times derived from it - e.g. interval 12 h and time 03:30 → runs at 03:30 and 15:30. Other intervals run relatively; the catch-up watchdog keeps them on track.
- Target directory - always set and pre-filled with the default
(
backup_dirfrom config.json, otherwise<data-dir>/backups). It can be changed freely - handy for a persistent/external volume; clearing the field restores the default on save.
Overdue backups are caught up
Section titled “Overdue backups are caught up”For intervals that cannot be expressed as fixed times of day, the schedule counts from instance start. So that an instance that restarts more often than the interval is long (e.g. due to regular updates) still gets backed up, a watchdog checks every few minutes: if the newest backup is older than the interval (or none exists yet), a backup is caught up immediately - shortly after startup, with no action required. A fresh manual backup also counts as covering the interval.
Restore
Section titled “Restore”Two paths:
- From history - select an earlier backup directly for restoration.
- From an uploaded archive - upload an
.lcmbak, even on a fresh instance (fresh-instance restore).
The restore runs via staging + apply-on-startup: LCM stages the
files to be restored and applies them on the next start.
Whether LCM restarts itself for this is controlled by RestoreAutoRestart or the
environment variable LCM_RESTORE_AUTO_RESTART - sensible only under a
process supervisor (systemd/Docker with a restart policy). If auto-restart is off,
the restore stays prepared and the operator starts manually.
The environment variable takes precedence over the UI setting (truthy
values are 1, true, yes, on). On the orderly restart LCM exits with a
non-zero exit code so that Restart=on-failure (systemd) or a Docker restart
policy kicks in:
[Service]Environment=LCM_RESTORE_AUTO_RESTART=1Restart=on-failure