Skip to content

Backups

The backup topic is where you turn protection on, check it and undo it. You start with one of two commands, and use the rest of this page afterwards:

  • flui backup quick-setup provisions storage with the provider you already have connected and protects every application on a cluster with it, in one step.
  • flui backup enable gives you more control: enable cluster for every application on a cluster, including the ones installed later, and one subcommand per kind of thing when you want to protect a single application.

What enable creates is a policy: a scope, a schedule, and one or more S3-compatible destinations. The API runs it as a job. The policy commands maintain what enable created (list, pause, delete). You do not create policies with them.

flui backup status tells you whether protection is set up, and flui backup list tells you whether it actually ran.

The volume snapshots of one application (taking one now, looking inside, restoring whole or file by file) are under flui app backup, near the end of this page.

Commands that turn protection on or read it for a cluster take -c, --cluster <name|id> and auto-detect the cluster when it is omitted. The listing commands (backup list, job list, policy list) take a cluster ID, and the commands that read data accept --json for machine-readable output.

The sections below follow the order you need them: getting started, turning protection on, checking it, then destinations, policies, jobs, restores and volume snapshots. Platform configuration comes last. It protects the installation itself rather than an application or a cluster.

flui backup quick-setup

Provisions backup storage using the provider already connected, and protects every application on a cluster with it, as enable cluster does. It replaces creating a destination, testing it and protecting the cluster by hand.

Terminal window
flui backup quick-setup # auto-detects the cluster
flui backup quick-setup -c production-eu --dry-run
FlagDefaultEffect
-c, --cluster <name|id>auto-detectWhich cluster to protect.
--dry-runoffReport what would be set up, and whether it can be, without doing it.
--schedule <cron>per kindOne cron schedule in UTC for every policy. Without it, each kind of backup keeps its own nightly time.
--retention-days <n>30How long database backups are kept.
--no-first-backupoffDo not run the first backups immediately.
--jsonoffMachine-readable output.

Run it with --dry-run first. It tells you whether the connected provider can give you storage before anything is created.

flui backup enable

CommandProtectsDoes not cover
enable clusterevery application on a cluster, including the ones installed later, each with the engine that fits itdatabases it does not recognise, which are listed as needing a decision
enable database <app>one database: continuously where the image allows it, with scheduled dumps otherwiseanything else
enable volumes <app>one application’s volumes, as nightly encrypted snapshots: uploads, media, generated filesa volume a database is writing to, which is refused and listed unless the app is stopped for the copy
enable platformFlui itself: the control-plane database, sealed to a recipientapplications

enable cluster is the usual starting point. Use the other three to protect one thing at a time. They create the same kind of policy enable cluster creates for each application.

These flags are common to database, volumes and platform:

FlagDefaultEffect
-D, --destination <spec>required<destId>[:primary|replica[:priority]]. Repeatable: pass it once per target to mirror across destinations.
--name <s>descriptiveName for this protection.
--schedule <cron>per kinde.g. "0 2 * * *" for 02:00 UTC daily. Without it: databases at 02:30 (continuous) or 03:00 (dumps), volumes at 03:30, the platform at 02:00, all UTC.
--retention-days <n>30How long each copy is kept. Volume snapshots follow their own rule instead (see below).
--retention-max-copies <n>noneCap on retained copies.
--[no-]enabledenabledCreate it paused with --no-enabled.
-c, --cluster <name|id>auto-detectWhich cluster.

flui backup enable cluster

Every application on the cluster gets a policy of its own:

  • a recognised database (PostgreSQL, MariaDB) gets continuous backup, or dumps when its image cannot ship its changes, and a first base copy right away;
  • every other application with volumes gets nightly snapshots;
  • Flui’s own components and applications that keep no data are skipped, and an application that already has a policy is left as it is;
  • applications installed later get theirs within minutes of their first successful deploy.
Terminal window
flui backup enable cluster -c production-eu -D <dest-id>
flui backup enable cluster -D <dest-id> -D <replica-id>:replica --before-deploy

It follows the work to the end and prints one line per application: what it got, or why it got nothing.

FlagDefaultEffect
-D, --destination <spec>none<destId>[:primary|replica]. One primary, and at most one replica, which receives a copy of the volume snapshots after each run. Required.
-c, --cluster <name|id>auto-detectWhich cluster.
--schedule <cron>per kindOne cron schedule in UTC for every policy.
--retention-days <n>30How long database backups are kept.
--before-deployoffAlso take a backup before each deploy of every application.
--[no-]first-backuponTake the first volume snapshot of each application now.
--no-waitoffReturn once protection is recorded, without following it.

The policies it creates are ordinary policies, listed by flui backup policy list like any other.

flui backup disable cluster

Stops giving new applications on a cluster a policy. The policies already created keep running; remove one with flui backup policy delete.

Terminal window
flui backup disable cluster -c production-eu

flui backup enable database <app>

Every change is shipped off-cluster as it happens, so the database can be restored to any moment in the retained window rather than to the last nightly copy. A database whose image cannot do that (one inside another application’s bundle, for instance) gets scheduled dumps instead, each restorable to the moment it was taken.

Terminal window
flui backup enable database my-api-db -D <dest-id>

To restore to a moment, use flui db pitr-restore.

flui backup enable volumes <app>

Use this for uploads, media and generated files. It takes nightly encrypted snapshots, each storing only what changed since the one before. Flui keeps the last 7 daily and 4 weekly snapshots, and always the most recent one. --keep-monthly adds 3 monthly ones, for about 30% more space. --retention-days does not apply to snapshots.

Terminal window
flui backup enable volumes my-api -D <dest-id> --exclude cache
FlagEffect
--exclude <volume>Leave a volume out. Repeatable; everything else is included, including volumes the application grows later.
--pauseStop the application for the length of each copy, so every volume is copied at rest. Each run records how long it was stopped.
--[no-]keep-monthlyAlso keep 3 monthly snapshots, or stop keeping them.

A volume a database is writing to is refused and named in the run, because a file copy of a running database does not restore. Redis, Valkey and SQLite are copied consistently while they run; anything else is listed as needing a decision until you pass --pause or --exclude for it.

When the application already has a volume policy (from enable cluster, for example), running this again with --pause, --exclude or --[no-]keep-monthly changes that policy instead of adding a second one. This is how you record a decision.

flui backup enable platform

Protects Flui’s own control-plane database, sealed so only the holder of the matching identity can open it. A rebuild starts from this backup when the cluster running Flui is gone.

Terminal window
flui backup platform init # on your machine, first
flui backup enable platform -D <dest-id>
FlagEffect
--recipient <age>The recipient the dump is sealed to. Defaults to the key flui backup platform init keeps in your vault. Without the matching identity nobody, including Flui, can open it.
--heartbeat-url <url>Pinged after each successful run, so you can detect when runs stop.

flui backup status

Shows what is protected, and how. For the whole installation it also lists, per cluster, whether every application is protected and what needs a decision: databases Flui does not recognise, and volumes the last snapshot had to refuse. Each comes with the two commands that resolve it: copy with the application stopped (enable volumes <app> --pause), or leave the volume out (enable volumes <app> --exclude <volume>).

Terminal window
flui backup status # the whole estate
flui backup status -a my-api # everything protecting one application
FlagEffect
-a, --app <name|slug|id>Narrow to one application.
-c, --cluster <name|id>With --app: the cluster the application is on. Auto-detected when omitted.
--jsonMachine-readable output.

For a database this prints a recoverable window. The up to time it shows is the end of the last base copy. Continuous shipping usually reaches later than that, so treat the time as a minimum.

flui backup list

Lists the backups that actually exist, for every engine.

Terminal window
flui backup list --app <app-id>
flui backup list --cluster <cluster-id>

status tells you whether protection is set up; list tells you whether it ran. A policy can be enabled and correct and still have produced nothing.

flui backup destination

A destination is an S3-compatible storage target where backup artifacts are written. Supported providers are hetzner_object_storage, scaleway_object_storage, ovh_object_storage, minio, and generic_s3.

flui backup destination create

Registers a new destination. Provider, endpoint, region and bucket are required. When you leave out the access and secret keys, the command asks for them. That is safer, because a value typed at the prompt never enters your shell history or the process list. Encryption defaults to flui_managed; pass --encryption-mode byo_passphrase to supply your own passphrase, which is asked for the same way.

Terminal window
flui backup destination create \
--name my-s3 --provider hetzner_object_storage \
--endpoint https://fsn1.your-objectstorage.com \
--region fsn1 --bucket flui-backups
flui backup destination create \
--name scw --provider scaleway_object_storage \
--endpoint https://s3.fr-par.scw.cloud \
--region fr-par --bucket flui-bkp
FlagDefaultEffect
--name <s>noneDisplay name (≤120 chars). Required.
--provider <p>noneStorage backend: hetzner_object_storage, scaleway_object_storage, ovh_object_storage, minio, generic_s3. Required.
--endpoint <url>noneS3 endpoint URL (e.g. https://s3.fr-par.scw.cloud). Required.
--region <code>noneS3 region. Required.
--bucket <name>noneTarget bucket. Required.
--access-key <k>promptedS3 access key.
--secret-key <s>promptedS3 secret key.
--prefix <s>noneOptional path prefix inside the bucket.
--encryption-mode <m>flui_managedflui_managed, byo_passphrase, or none.
--encryption-passphrase <s>promptedPassphrase to use with --encryption-mode=byo_passphrase.
--force-path-styleoffForce path-style S3 URLs (needed for MinIO and some providers).
--use-sseoffUse server-side encryption (SSE-S3) at the provider.
--cost-per-gb-month-cents <n>noneWhat the storage costs, in euro cents per GB per month (e.g. 1.606), used for estimates.

flui backup destination list

Lists the destinations configured in the API, with provider, region and bucket, usage, and health when available.

Terminal window
flui backup destination list
flui backup destination list --json

flui backup destination show <id>

Shows one destination in full, including endpoint, prefix, encryption mode, health, and reported usage.

Terminal window
flui backup destination show <dest-id>
flui backup destination show <dest-id> --json

flui backup destination test <id>

Checks that a destination is reachable by running a real S3 PUT, GET and DELETE against the bucket. Use it right after create to confirm the credentials and endpoint work.

Terminal window
flui backup destination test <dest-id>

flui backup destination set-cost <id> [<cents>]

Sets what a destination costs, in euro cents per GB per month, so backup cost estimates use your price. --list-price goes back to the published price Flui knows for the provider.

Terminal window
flui backup destination set-cost <dest-id> 1.606
flui backup destination set-cost <dest-id> --list-price

flui backup destination delete <id>

Removes a destination from the API. Artifacts already in the bucket are not removed; only the registration is deleted. It asks you to confirm; skip that with -y, --yes.

Terminal window
flui backup destination delete <dest-id>
flui backup destination delete <dest-id> --yes

flui backup policy

A policy is what flui backup enable creates: a scope, a schedule and one or more destinations. The API runs it on that schedule (and on demand via backup job run), producing artifacts subject to its retention. The commands in this section list, inspect, pause and remove policies that already exist.

flui backup policy create does not create a policy. It prints which command to use and exits. Create policies with flui backup enable, where the subcommand says which kind you mean.

flui backup policy list

Lists policies, optionally filtered to one cluster. Each row shows the name, the engine and profile or scope, cluster, cron schedule, and whether it is disabled.

Terminal window
flui backup policy list
flui backup policy list --cluster <cluster-id>
flui backup policy list --json

flui backup policy show <id>

Shows one policy: its schedule in words and the next run, its health and last good run, the applications it covers, retention, its destination list (each with role and priority), and the last five runs.

Terminal window
flui backup policy show <policy-id>
flui backup policy show <policy-id> --json

flui backup policy delete <id>

Deletes a policy. Existing backups are kept; only the policy and its schedule are removed. It asks you to confirm; skip that with -y, --yes.

Terminal window
flui backup policy delete <policy-id>
flui backup policy delete <policy-id> --yes

flui backup policy pause <id>

Turns a policy’s schedule off. The policy’s scope, schedule, retention and destinations stay as configured; the API stops queueing new runs from it until someone resumes it. flui backup job run still works on a paused policy, so you can still take an on-demand backup. Only the cron schedule stops.

One exception: a database-class policy ships every change continuously, and pausing it does not stop that stream, because stopping it would leave a gap in the recovery window. Deleting the policy is the only way to stop it.

Terminal window
flui backup policy pause <policy-id>

flui backup policy resume <id>

Turns a paused policy’s schedule back on.

Terminal window
flui backup policy resume <policy-id>

flui backup job

A job is one run of a policy, either scheduled or on demand. A job shows a backup’s status, timing, bytes transferred, and any error.

flui backup job run

Triggers an on-demand backup for a given policy, outside its normal schedule. Returns the queued job’s ID so you can track it with backup job show.

Terminal window
flui backup job run --policy <policy-id>

flui backup job list

Lists the backup jobs for a cluster. --cluster (cluster ID) is required.

Terminal window
flui backup job list --cluster <cluster-id>
flui backup job list --cluster <cluster-id> --json

flui backup job show <id>

Shows one job: its policy, status, start and completion times, bytes transferred, and error message if it failed.

Terminal window
flui backup job show <job-id>
flui backup job show <job-id> --json

flui backup restore

Shows the history of restores. You start a restore with the command that fits what you are restoring:

flui backup restore list

Lists restore jobs, with status, target kind, and target cluster.

Terminal window
flui backup restore list
flui backup restore list --json

flui backup restore show <id>

Shows one restore job: status, source artifact and destination, target, timing, and error message if it failed.

Terminal window
flui backup restore show <restore-id>
flui backup restore show <restore-id> --json

flui backup restore preview

Shows what a backup holds in its storage (objects and bytes) before you restore it. Both flags are required.

Terminal window
flui backup restore preview --artifact <artifact-id> --source-destination <dest-id>

flui app backup

The volume snapshots of one application. The nightly ones come from its policy; these commands take one now, look inside, restore and delete. Each takes the application’s name or slug, and -c, --cluster <name|id>.

flui app backup create <name>

Takes a snapshot now. A snapshot you take yourself stays until you delete it, and does not replace a nightly one.

Terminal window
flui app backup create my-app -D <dest-id>
flui app backup create my-app -D <dest-id> --volume uploads --no-wait
FlagEffect
-D, --destination <id>A registered destination: the copy becomes an encrypted snapshot in the application’s own repository there.
-v, --volume <name>Which volume, when the application has more than one.
--pauseStop the application for the length of the copy, so a volume a database is writing to is copied at rest.
--allow-inconsistentCopy it while a database writes anyway. The copy may not restore cleanly.
--no-waitReturn once the backup is queued instead of following it.

The backup runs in the background. Without --no-wait, the command follows it to the end.

Without --destination the copy is a full, unencrypted copy instead of a snapshot. It goes to a bucket passed with -b, --bucket and -e, --endpoint, or to one the cluster’s provider creates. Use a destination when you can.

flui app backup list <name>

The application’s volume backups, newest first. SIZE is what a restore writes back; ADDED is what the backup added to the destination.

Terminal window
flui app backup list my-app
flui app backup list my-app -o json

flui app backup browse <name> <backup> [path]

Lists a folder inside a snapshot, read-only. Use it to find the paths to give restore --path.

Terminal window
flui app backup browse my-app 3f2a91c0
flui app backup browse my-app 3f2a91c0 uploads/2026

flui app backup restore <name> <backup>

A whole snapshot is written into a new volume beside the application, which keeps running on its current data until you switch. With --path, only the named files or folders are written back into the live volume.

Terminal window
flui app backup restore my-app 3f2a91c0
flui app backup restore my-app 3f2a91c0 --swap
flui app backup restore my-app 3f2a91c0 --to my-app-copy --swap
flui app backup restore my-app 3f2a91c0 --path uploads/report.pdf --path config
flui app backup restore my-app 3f2a91c0 --path uploads --into restored-uploads
FlagEffect
--swapSwitch the application to the restored volume right away. It restarts; the data it used before is kept as a separate volume.
--to <app>Restore into another application instead.
-v, --volume <name>The target application’s volume, when it has more than one.
-p, --path <path>Restore only this file or folder, relative to the volume root. Repeatable.
--into <dir>With --path: write under this folder instead of over the current files.
-y, --yesDo not ask before writing over files in the live volume.

flui app backup delete <name> <backup>

Removes a snapshot and its record from the destination. It cannot be restored afterwards. The command asks first; --yes skips the question.

Terminal window
flui app backup delete my-app 3f2a91c0
flui app backup delete my-app 3f2a91c0 --yes

flui app backup before-deploy <name>

Takes a backup before each deploy of the application. For a database with continuous backup this is a restore point, and the deploy waits the few seconds it takes. For everything else it is a dump or a volume snapshot, which is started and not waited for. It uses the policies that already protect the application.

Terminal window
flui app backup before-deploy my-app
flui app backup before-deploy my-app --required
flui app backup before-deploy my-app --off
FlagEffect
--requiredFail the deploy when the backup before it cannot be taken. Without it the deploy goes ahead and the failure is logged.
--offStop taking a backup before each deploy.

flui app backup skip <name>

Records that the application is not to be backed up, so flui backup status stops listing it as needing a decision. -n, --note says why; --undo reverses it.

Terminal window
flui app backup skip my-app --note "rebuilt from source, nothing to keep"
flui app backup skip my-app --undo

flui backup platform

Everything above protects an application or a cluster. A platform-class policy protects this installation’s own control plane: the database holding every user, API key, provider token and application record Flui has.

That backup cannot be sealed with a key the control plane holds itself, because if the master is lost, a key stored on the master is lost with it. So a platform backup is encrypted to an age key pair you generate on your own laptop. Only the public half, the recipient, is registered on the policy. The private identity never touches the master.

flui backup platform init

Generates that identity entirely on your machine and keeps it sealed in your vault next to the rest of the profile’s secrets, so the vault passphrase is the only one you need to remember. Needs the vault unlocked. Prints the public recipient.

Because the vault lives on one machine, init also writes a recovery copy (default ~/flui-<profile>-platform-recovery.age) sealed with the same vault passphrase. A rebuild starts from it if this machine is lost too. Run init again at any time to write a fresh copy; the key in the vault is kept.

Move the recovery copy off this machine and off the master. Flui does not hold one. Lose both the vault and the copy, or the passphrase, and every platform backup becomes permanently unrecoverable.

Terminal window
flui backup platform init
flui backup platform init --out /Volumes/usb/flui-recovery.age
FlagDefaultEffect
--policy <id>nonePlatform backup policy to register the recipient on.
--heartbeat-url <url>noneDead-man’s-switch URL the master pings while its last platform backup stays fresh. Only takes effect together with --policy.
--out <path>~/flui-<profile>-platform-recovery.ageWhere to write the recovery copy.
--passphrase <s>noneYour vault passphrase, checked against the vault. Prompted if omitted.
--rotateoffReplace the key in the vault. The previous one is kept, so older backups still open, and goes into the recovery copy too. Register the new recipient on your policies afterwards with --policy.
--forceoffOverwrite an existing file at --out.
--jsonoffPrint {recipient, out, outcome, keys} as JSON. Requires --passphrase, since it cannot prompt.

flui backup enable platform creates the policy and seals it to the key init put in your vault. Run init first, on your own machine, or pass --policy here to register the recipient on a policy that already exists.

flui backup platform download

Fetches the two files of a platform backup, the key bundle and the dump of Flui’s own state, so flui backup platform restore can open them. The API hands out short-lived links, so the storage credentials never leave it, and the files stay sealed to your key.

Terminal window
flui backup platform download
flui backup platform download --job <backup-job-id> --out ./rebuild-input
FlagEffect
--job <id>The backup to fetch. Defaults to the newest.
--out <dir>Where to write. Defaults to ./flui-platform-backup-<job>.
--forceOverwrite files already in --out.
--jsonPrint the job, its date and the files written as JSON.

flui backup platform restore

Opens a platform backup. It decrypts the sealed key bundle and the dump of Flui’s own state with the key in your vault (or, when this machine is gone, the recovery copy) and writes out everything a fresh installation needs to become this one again. It runs on your machine and sends nothing anywhere.

Terminal window
flui backup platform restore --bundle keybundle.age --dump flui-pg.dump.gz.enc
flui backup platform restore --bundle keybundle.age --dump flui-pg.dump.gz.enc \
--identity ~/flui-default-platform-recovery.age
FlagEffect
--bundle <file>The sealed key bundle. Required.
--dump <file>The encrypted dump from the same run. Required.
--identity <file>Open with the recovery copy instead of the vault.
--passphrase <s>The recovery copy’s passphrase. Prompted if omitted.
--out <dir>Where to write. Defaults to ./flui-rebuild.
--forceOverwrite an existing output directory.

Rebuild the control plane explains what to do with the files it writes.

flui backup platform status

Lists every platform-class policy: its recipient, whether a dead-man’s-switch URL is set, its schedule and next run, its health, the last good run and the last run. A paused platform policy is marked [disabled].

Terminal window
flui backup platform status
flui backup platform status --json

flui backup velero uninstall [<cluster>]

Removes Velero, a cluster backup engine, from a cluster where Flui installed it: its controller, node agent, bucket credentials and the rest of what Flui set up for it. Only what Flui installed is removed. The backups it wrote stay in their destination, and Flui cannot restore them. Running it again continues where it stopped.

Terminal window
flui backup velero uninstall --plan
flui backup velero uninstall production --yes
FlagEffect
--planShow what would be removed and change nothing.
-y, --yesDo not ask for confirmation.
--no-waitStart the removal and return its operation id.