In short
A complete backup is first the data directory — including the secret.key file, the encryption key without which restored database passwords and git tokens would be unreadable. Add what lives elsewhere: the login secret key, the encryption key if you supply it yourself, and the PostgreSQL database if you use one.
What to back up
The data directory holds nearly everything; three things may live outside it, depending on your configuration.
Outside the folder
A backup without the encryption key is an incomplete backup
Restore the application database without secret.key — or without the LINKR_ENCRYPTION_KEY you were supplying — and the instance will come back, your users will sign in, but every remembered database password, every git token and every connection secret will be unreadable, with no visible error, and will have to be re-entered by hand. The login secret key, by contrast, can be replaced harmlessly: at worst everyone signs in again. See Configuration.
So your backup holds a key
By default the folder’s archive brings together the encrypted secrets and the key that opens them. Protect it like the secrets themselves: restricted access, encrypted archive. If your policy forbids that, supply the key through LINKR_ENCRYPTION_KEY and back it up separately — the database alone then decrypts nothing.
What you may exclude
The caches are rebuildable. Excluding them shrinks the backup considerably; at worst the first environment build after a restore takes longer. One caveat: on an instance with no network access, keep _duckdb_ext/, which the server could not download again.
Backing up cleanly
The difficulty is not copying, it is copying a consistent state: a copy taken while a write is in progress can contain a half-written database.
Stop the instance, or take a snapshot
The safest route is stopping the containers for the duration of the copy. Failing that, a filesystem or volume snapshot gives a consistent point with no downtime.
Copy the folder
With your usual tools, preserving permissions. This is where choosing a mounted folder over a named Docker volume pays off: the folder backs up like any other.
Record the version
Keep the version number of the images alongside the backup. A backup does not restore onto an older version — see below.
docker compose -f docker-compose.hub.yml down
tar czf linkr-$(date +%F).tar.gz -C /srv linkr
docker compose -f docker-compose.hub.yml up -d
Restoring
Put the folder back — secret.key included —, supply the same environment variables, and start with a version at least equal to the one the backup came from. Any needed migrations apply by themselves on start.
You do not restore onto an older version
The database schema moves forward with upgrades, and those migrations do not replay backwards. A backup taken on a recent version will not come back on an earlier one: that is why the version must be recorded at backup time.
Test a restore at least once
A backup that has never been restored is a hypothesis, not a guarantee. Bring one back on a test machine: sign in, open a project, display a dashboard, and above all connect to a database — that last step is what reveals a missing encryption key.
Backing up differently: git
The data directory protects the instance. Git versioning protects the work, and the two complement each other.
An entity linked to a remote repository has, by construction, a copy outside your server: cohort definitions, scripts, dashboards. If the instance disappears, that work is recovered by cloning the repositories, even with no backup at hand.
But git does not back up data
Data files are excluded from versioning unless explicitly marked. A git repository is therefore not a backup of your datasets — see Git versioning.
Accounts, separately
The Settings › Backup & sync tab exports and re-imports organizations, users and roles, as an archive or to a git repository. It is useful for carrying a configuration from one instance to another, or for keeping track of how roles evolve.
Passwords are never exported
An imported user with no password lands disabled and must be given one before they can sign in. This export is therefore not a substitute for a backup: it carries a configuration, not accounts usable as they stand.
What the backup does not cover
- External databases. A PostgreSQL or Oracle database queried by Linkr stays the responsibility of whoever operates it: Linkr only holds its address.
- Files pointed at by path. A warehouse placed on the server and pointed at without copying is not in the data directory, nor is a database Linkr created in a folder on the server rather than in its own folder — both belong to the server’s own backup. See Files on the server.
- A browser-mode installation. The data lives in each person’s browser, out of an administrator’s reach. Only manually exporting a project puts it somewhere safe.
Going further
- Configuration — the data directory, folder by folder.
- Production install — the volume to mount, and upgrading.
- Git versioning — the other safety net.
- Import and export — taking an entity out of an instance.