Operations
Keep Monita healthy: back it up, restore it, watch it from outside, and upgrade it.
Backups and restore
Monita writes monita-YYYYMMDD.db to MONITA_BACKUP_DIR at 01:00 UTC and keeps the newest MONITA_BACKUP_KEEP (7). To restore one:
systemctl stop monita
mv /var/lib/monita/monita.db /var/lib/monita/monita.db.broken
rm -f /var/lib/monita/monita.db-wal /var/lib/monita/monita.db-shm
install -m 0600 -o monita /var/backups/monita/monita-20261016.db /var/lib/monita/monita.db
systemctl start monita
A backup is a plain SQLite file: sqlite3 monita-20261016.db 'PRAGMA integrity_check' checks it.
Watch Monita from outside
Monita cannot alert about its own outage. Run a second Monita at another site and give each a heartbeat on the other:
- On Monita B, create a heartbeat named
monita-a, runs every 1 minute, can be late by 5 minutes, alert level critical. - On Monita A, set
MONITA_PING_URLto that heartbeat's ping URL and restart. A pings it at start and every 60 seconds. - Do the same in the other direction.
If one site loses power, the other sends "monita-a missed its heartbeat". A free Better Stack heartbeat works the same way in place of Monita B. GET /healthz returns 503 when the database fails or the scheduler stops ticking, for a load balancer or an uptime check.
Monita picks its mail server in this order:
- The server a super admin saved on Admin, Outgoing email.
- The
MONITA_SMTP_URLvariable in the env file. - None. Monita writes each email to its log.
So MONITA_SMTP_URL is a fallback. Saving a server on the page replaces it for the next email, with no restart. Remove saved server returns to the variable.
Use Test connection to check a server before you save it. Use Send a test email to see a real delivery. The page also counts emails sent, waiting and failed. See Admin and roles.
The saved password is stored as you entered it. Only the database file holds it. Back up that file with care.
Lost super admin password
systemctl stop monita # the running service locks the database file
sudo monita admin reset-password --email you@company.co.id
systemctl start monita
The command asks for the new password without echo (or reads stdin in a script) and signs the admin out everywhere. A tech lead or supervisor who lost the password gets a new invite from a super admin. If nobody can sign in at all, use reset-sign-in below.
Lost authenticator and recovery codes
Any user who lost both can get back in. No super admin has to be signed in.
systemctl stop monita # the running service locks the database file
sudo monita admin reset-sign-in --email you@company.co.id
systemctl start monita
In Docker:
docker compose stop
docker compose run --rm monita admin reset-sign-in --email you@company.co.id
docker compose up -d
The command turns two-factor off and stops the old password. It queues an email with a link to set a new password and prints the link too. Monita sends the email when it runs. The link works once and lasts 72 hours. An unknown or disabled user gets the error No active user has this email.
Upgrade
Take a backup, install the new binary over the old one, and restart. Migrations run at start, before /healthz answers. A large database can take a few seconds: v1.1 took 11 s on 3 million checks. The first start of v1.1 also rewrites the database file once, so that it gives deleted space back to the disk. This takes about 4 s for 350 MB and needs that much free disk. Without that space, Monita starts, logs a warning, and the file keeps its largest size. To go back to an older version, restore the backup, because an older binary does not know the newer tables. On Docker Compose, back up the data volume, then run docker compose pull && docker compose up -d (see Install).
systemctl stop monita && cp /var/lib/monita/monita.db /var/backups/monita/pre-upgrade.db
install -m 0755 monita /usr/local/bin/monita
systemctl start monita
Cut a release (maintainers)
Push a v* tag that matches the version in Cargo.toml. release.yml builds the Linux, macOS and Windows archives for amd64 and arm64, boots each one, pushes the image to GHCR, and opens a draft GitHub release with checksums.txt. Only a repository admin can push a v* tag.