Skip to main content

Persistence & Backup

Every piece of durable collector state lives in SQLite. That covers the onboarded device registry, inventory, alerts, problems, correlation state, and the metric buffers. There is no PostgreSQL and no Keycloak on the collector by design, so persistence is a plain matter of files on disk. This guide covers where those files live, why they sit on a host bind mount, and how to back them up, migrate them, and restore them.

Where the state lives

All services mount one host directory at /data. The host path is AIOPS_DATA_DIR, which defaults to /opt/aiops/data and is set in deploy/docker-compose/.env. Each engine owns its own file, so a store can be inspected or restored in isolation.

StoreFileOwner service
Device registry (onboarding)collector.dbuniversal-collector
Inventoryinventory.dbinventory-engine
Alertsalerts.dbalerting-engine
Problemsproblems.dbproblem-engine
Correlationcorrelation.dbcorrelation-engine
SNMP buffersnmp_buffer.dbuniversal-collector
eBPF bufferebpf_buffer.dbebpf-collector
Synthetic checkssynthetic.dbsynthetic-prober
Security posturesecurity.dbsecurity-posture
Business impactbusiness.dbbusiness-impact
SLOslo.dbslo-engine
Capacitycapacity.dbcapacity-forecast
Auto-discoverydiscovery.dbauto-discovery
Netshot bridgenetshot.dbnetshot-sync
SaaS sync cursorsaas_sync.jsonsaas-sync
HA passive inventorypassive/inventory-passive.dbinventory-engine-passive

Why a bind mount, not a named volume

Onboarded devices used to vanish because the stack kept its state in a Docker named volume, and a named volume is destroyed by docker compose down -v, docker volume prune, and docker system prune --volumes. A host bind mount avoids all of that:

  • It survives image rebuilds, --force-recreate, and every prune or down -v.
  • It sits at a known, inspectable path that you can snapshot or copy off-box.
  • It turns backups into a plain file operation.

A docker compose up -d --build <svc> never touches this data. Only an explicit removal of the host directory does.

First-time setup and migration

Run this once on the host. If you are moving from the old named volume, migrate the existing data before recreating the stack so nothing is lost.

cd deploy/docker-compose
cp .env.example .env # sets AIOPS_DATA_DIR=/opt/aiops/data
sudo mkdir -p /opt/aiops/data/passive

# Copy any existing data out of the old named volume (skip if starting fresh):
docker run --rm \
-v aiops_sqlite-data:/from -v /opt/aiops/data:/to \
alpine sh -c 'cp -a /from/. /to/ 2>/dev/null || true'
# The old volume may be named "docker-compose_sqlite-data" instead of
# "aiops_sqlite-data" depending on the compose project name. Check with:
# docker volume ls | grep sqlite-data

docker compose up -d # recreates services on the bind mount

Verify the device registry survived the move: open the collector WebUI and confirm your devices are still listed. If you prefer the shell, check that the collector came back up cleanly:

cd /opt/techforcz/collector/deploy/docker-compose
docker compose ps
docker compose logs --tail 20 universal-collector

Backups

scripts/aiops-backup.sh writes a consistent, timestamped .tar.gz of every *.db. It uses the SQLite online .backup when sqlite3 is present, and it keeps the newest RETENTION archives, which defaults to 14.

# manual
AIOPS_DATA_DIR=/opt/aiops/data BACKUP_DIR=/opt/aiops/backups \
./scripts/aiops-backup.sh

# nightly at 02:30 via cron (crontab -e)
30 2 * * * AIOPS_DATA_DIR=/opt/aiops/data BACKUP_DIR=/opt/aiops/backups \
/path/to/repo/scripts/aiops-backup.sh >> /var/log/aiops-backup.log 2>&1

For durability beyond the box itself, point BACKUP_DIR at an NFS mount or sync /opt/aiops/backups to object storage.

Restore

docker compose stop # quiesce writers
./scripts/aiops-restore.sh # newest backup, or pass a specific .tar.gz
docker compose up -d

aiops-restore.sh defaults to the newest backup. Pass a specific .tar.gz path to roll back to an earlier point.

Operational rules

  • Never run docker compose down -v on a live appliance. That flag is only for a deliberate wipe. To halt the stack, use docker compose stop or docker compose down without -v.
  • Rebuild a single service with docker compose up -d --build <svc>. This leaves the data untouched.
  • The WebUI Export on the Device Inventory page is a convenient point-in-time export of the device list. Treat it as a complement to the DB backups, not a replacement.