Backups and upgrades
Checkend keeps all data in one data folder, for example /var/lib/checkend. This page shows how to back it up, restore it, limit its size and upgrade the server.
What a backup contains
Section titled “What a backup contains”app.sqlite(the metadata) andlake.sqlite(the lake catalog), as consistent copies,- the Parquet files of the lake (with the lake on a bucket, the backup reads them from the bucket),
secret.key,manifest.json, with the size and the SHA-256 of each file.
The event log is not in a backup. The events that were not yet in the lake at the time of the backup are lost after a restore.
Make a backup by hand
Section titled “Make a backup by hand”A backup works while the server runs:
checkend backup create --data /var/lib/checkend --to /backups/checkendWith the lake on a bucket, add the same --lake-bucket as the server:
checkend backup create --data /var/lib/checkend --to /backups/checkend \ --lake-bucket s3://<bucket>/checkendThe scheduled backup uses the --lake-bucket flag of the server.
List the backups in a folder:
checkend backup list --from /backups/checkendScheduled backups
Section titled “Scheduled backups”Add these flags to CHECKEND_FLAGS in /etc/checkend/checkend.env:
--backup-dir /backups/checkend --backup-every 24h --backup-keep 7| Flag | Meaning | Default |
|---|---|---|
--backup-dir |
A folder, or s3://<bucket>/<prefix>. Without it, there is no scheduled backup. |
None |
--backup-every |
The interval. | 24 hours |
--backup-keep |
The count of backups to keep. | 7 |
With the installer, the systemd service can write only to /var/lib/checkend. Add the backup folder to ReadWritePaths:
-
Open an override file:
Terminal window sudo systemctl edit checkend -
Add these lines:
[Service]ReadWritePaths=/backups/checkend -
Restart the service:
Terminal window sudo systemctl restart checkend
The bucket
Section titled “The bucket”An S3-compatible bucket can hold the backups and the Parquet files of the lake. Examples are AWS S3, MinIO, Cloudflare R2 and Hetzner Object Storage. The bucket must exist. Make it in the console of your provider.
Set the bucket access in the environment of the server. For the service, put the variables in /etc/checkend/checkend.env:
| Variable | Meaning | Default |
|---|---|---|
CHECKEND_S3_ENDPOINT |
The endpoint URL. | https://s3.<region>.amazonaws.com |
CHECKEND_S3_REGION |
The region. | us-east-1 |
CHECKEND_S3_ACCESS_KEY_ID |
The access key ID. | None |
CHECKEND_S3_SECRET_ACCESS_KEY |
The secret access key. | None |
CHECKEND_S3_URL_STYLE |
path, or vhost for the bucket in the host name. |
path |
Checkend uses Signature Version 4. An example for Hetzner Object Storage in fsn1:
CHECKEND_S3_ENDPOINT=https://fsn1.your-objectstorage.comCHECKEND_S3_REGION=fsn1CHECKEND_S3_ACCESS_KEY_ID=...CHECKEND_S3_SECRET_ACCESS_KEY=...CHECKEND_S3_URL_STYLE=vhostHetzner documents the endpoint https://<location>.your-objectstorage.com and URLs with the bucket in the host name.
Backups in the bucket
Section titled “Backups in the bucket”Use s3://<bucket>/<prefix> in place of a folder, in --backup-dir, --to and --from:
checkend backup create --data /var/lib/checkend --to s3://<bucket>/backupsThe lake on the bucket
Section titled “The lake on the bucket”The Parquet files of the lake can go to the bucket. The lake catalog (lake.sqlite) and the metadata (app.sqlite) stay in the data folder.
-
Add
--lake-bucket s3://<bucket>/checkendtoCHECKEND_FLAGSin/etc/checkend/checkend.env. -
For a server that already has data, stop the server:
Terminal window sudo systemctl stop checkend -
Copy the Parquet files to the bucket. A second run copies only the new files.
Terminal window sudo -u checkend env $(grep CHECKEND_S3 /etc/checkend/checkend.env | xargs) \checkend lake push --data /var/lib/checkend --to s3://<bucket>/checkend -
Start the server:
Terminal window sudo systemctl start checkend -
Run
checkend doctor. The checklake_filesmust be OK.Terminal window checkend doctor --data /var/lib/checkend --lake-bucket s3://<bucket>/checkend -
When the server works on the bucket, delete
/var/lib/checkend/objects.
With --lake-bucket, the first start also downloads the DuckDB extension httpfs. DuckDB keeps the bucket key in memory only. The writer sends new data to the bucket about every 5 seconds. The compaction job merges the small files each hour. The retention and the compaction also work on the bucket.
The server does not start when the catalog names data files and the lake store has none of them. The cause is a wrong --lake-bucket, or a missing checkend lake push. The message tells you what to do.
Litestream
Section titled “Litestream”Litestream copies app.sqlite and lake.sqlite to the bucket each second. It is optional, and Checkend does not start it. Checkend was tested with Litestream v0.5.17.
The Checkend source has an example configuration, deploy/litestream.yml. It takes its values from the environment. Copy it to the server, and give its path to -config:
CHECKEND_DATA=/var/lib/checkend CHECKEND_LITESTREAM_BUCKET=<bucket> \CHECKEND_LITESTREAM_PREFIX=checkend/litestream \CHECKEND_S3_ENDPOINT=... CHECKEND_S3_REGION=... CHECKEND_S3_ACCESS_KEY_ID=... CHECKEND_S3_SECRET_ACCESS_KEY=... \ litestream replicate -config litestream.ymlRun Litestream as the user checkend, as its own systemd service. checkend doctor shows a litestream check. With the lake on a bucket, it warns when Litestream does not copy lake.sqlite.
Restore from the bucket
Section titled “Restore from the bucket”Use these steps on a new server with the same bucket.
-
Install Checkend with
--no-start. -
Copy
secret.keyfrom a backup into the new data folder. Give it mode 0600 and the ownercheckend. -
Restore the two SQLite files into the data folder:
-
With Litestream:
Terminal window litestream restore -config litestream.yml -o /var/lib/checkend/app.sqlite /var/lib/checkend/app.sqlitelitestream restore -config litestream.yml -o /var/lib/checkend/lake.sqlite /var/lib/checkend/lake.sqlite -
Without Litestream, restore the newest backup. The restore writes a Parquet file to the bucket only when the bucket does not have it.
Terminal window checkend backup restore --from s3://<bucket>/backups --data /var/lib/checkend \--lake-bucket s3://<bucket>/checkend
-
-
Add the same
--lake-buckettoCHECKEND_FLAGS. -
Start the server.
-
Run
checkend doctor. The checkslake_filesanddata_foldermust be OK.
The events of the last seconds before the loss are lost. They were in the event log, and not yet in the lake.
Restore a backup
Section titled “Restore a backup”-
Stop the server:
Terminal window sudo systemctl stop checkend -
Restore the newest backup:
Terminal window checkend backup restore --from /backups/checkend --data /var/lib/checkendTo restore an older backup, add
--id <id>. Get the ID fromcheckend backup list. With the lake on a bucket, add--lake-bucket. The restore then writes only the Parquet files that the bucket does not have. -
Start the server:
Terminal window sudo systemctl start checkend
The restore checks every file before it writes. A data folder that already has data needs --force. The old data then moves to a folder next to it.
Retention
Section titled “Retention”Checkend keeps the raw events for 24 months by default. A nightly job deletes the older months as whole months.
- The daily rollups stay permanently, so the numbers of old days stay.
- The search rows stay permanently.
- After a month is deleted, a visitor counts one time on each day of that month.
Show and change the retention (admin):
ce retentionce retention set analytics --months 18 --dry-runce retention set analytics --months 18The disk guard
Section titled “The disk guard”The disk guard protects the server from a full disk. It runs every 10 minutes.
When the disk use goes above the limit, it deletes the oldest raw month first. It never deletes the current or the previous month. The rollups stay.
| Flag | Meaning | Default |
|---|---|---|
--disk-limit |
The disk use in percent above which the guard deletes. 0 turns it off. |
90 |
--disk-budget |
The raw-data budget of a module, for example analytics=50GiB. |
None |
--disk-guard-every |
The interval. | 10 minutes |
The disk guard tells you in three ways:
- an audit entry
data.delete_rawfor each deleted month, - the webhook event
disk.pressure, - a failed
diskcheck ince healthandcheckend doctor.
Upgrades
Section titled “Upgrades”With the installer
Section titled “With the installer”-
Make a backup.
-
Run the installer again:
Terminal window curl -fsSL [INSTALL_URL] | sudo shIt downloads the new version only when the version is different. It replaces the binaries and restarts the server.
-
Check the server:
Terminal window checkend doctor --data /var/lib/checkend --public-url https://stats.example.com
With Docker
Section titled “With Docker”- Make a backup.
- Pull the new image.
- Start a new container on the same volume.
Migrations
Section titled “Migrations”The new binary runs the pending migrations at start. You never run a migration by hand. Migrations only go forward.
Before it migrates app.sqlite, Checkend copies the file to app.sqlite.before-migration-<n> (mode 0600). This is the rollback copy.
Check the health
Section titled “Check the health”After a backup, a restore or an upgrade, run the checks in Troubleshooting.