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-setupprovisions storage with the provider you already have connected and protects every application on a cluster with it, in one step.flui backup enablegives you more control:enable clusterfor 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.
flui backup quick-setup # auto-detects the clusterflui backup quick-setup -c production-eu --dry-run| Flag | Default | Effect |
|---|---|---|
-c, --cluster <name|id> | auto-detect | Which cluster to protect. |
--dry-run | off | Report what would be set up, and whether it can be, without doing it. |
--schedule <cron> | per kind | One cron schedule in UTC for every policy. Without it, each kind of backup keeps its own nightly time. |
--retention-days <n> | 30 | How long database backups are kept. |
--no-first-backup | off | Do not run the first backups immediately. |
--json | off | Machine-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
| Command | Protects | Does not cover |
|---|---|---|
enable cluster | every application on a cluster, including the ones installed later, each with the engine that fits it | databases 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 otherwise | anything else |
enable volumes <app> | one application’s volumes, as nightly encrypted snapshots: uploads, media, generated files | a volume a database is writing to, which is refused and listed unless the app is stopped for the copy |
enable platform | Flui itself: the control-plane database, sealed to a recipient | applications |
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:
| Flag | Default | Effect |
|---|---|---|
-D, --destination <spec> | required | <destId>[:primary|replica[:priority]]. Repeatable: pass it once per target to mirror across destinations. |
--name <s> | descriptive | Name for this protection. |
--schedule <cron> | per kind | e.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> | 30 | How long each copy is kept. Volume snapshots follow their own rule instead (see below). |
--retention-max-copies <n> | none | Cap on retained copies. |
--[no-]enabled | enabled | Create it paused with --no-enabled. |
-c, --cluster <name|id> | auto-detect | Which 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.
flui backup enable cluster -c production-eu -D <dest-id>flui backup enable cluster -D <dest-id> -D <replica-id>:replica --before-deployIt follows the work to the end and prints one line per application: what it got, or why it got nothing.
| Flag | Default | Effect |
|---|---|---|
-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-detect | Which cluster. |
--schedule <cron> | per kind | One cron schedule in UTC for every policy. |
--retention-days <n> | 30 | How long database backups are kept. |
--before-deploy | off | Also take a backup before each deploy of every application. |
--[no-]first-backup | on | Take the first volume snapshot of each application now. |
--no-wait | off | Return 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.
flui backup disable cluster -c production-euflui 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.
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.
flui backup enable volumes my-api -D <dest-id> --exclude cache| Flag | Effect |
|---|---|
--exclude <volume> | Leave a volume out. Repeatable; everything else is included, including volumes the application grows later. |
--pause | Stop 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-monthly | Also 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.
flui backup platform init # on your machine, firstflui backup enable platform -D <dest-id>| Flag | Effect |
|---|---|
--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>).
flui backup status # the whole estateflui backup status -a my-api # everything protecting one application| Flag | Effect |
|---|---|
-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. |
--json | Machine-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.
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.
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| Flag | Default | Effect |
|---|---|---|
--name <s> | none | Display name (≤120 chars). Required. |
--provider <p> | none | Storage backend: hetzner_object_storage, scaleway_object_storage, ovh_object_storage, minio, generic_s3. Required. |
--endpoint <url> | none | S3 endpoint URL (e.g. https://s3.fr-par.scw.cloud). Required. |
--region <code> | none | S3 region. Required. |
--bucket <name> | none | Target bucket. Required. |
--access-key <k> | prompted | S3 access key. |
--secret-key <s> | prompted | S3 secret key. |
--prefix <s> | none | Optional path prefix inside the bucket. |
--encryption-mode <m> | flui_managed | flui_managed, byo_passphrase, or none. |
--encryption-passphrase <s> | prompted | Passphrase to use with --encryption-mode=byo_passphrase. |
--force-path-style | off | Force path-style S3 URLs (needed for MinIO and some providers). |
--use-sse | off | Use server-side encryption (SSE-S3) at the provider. |
--cost-per-gb-month-cents <n> | none | What 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.
flui backup destination listflui backup destination list --jsonflui backup destination show <id>
Shows one destination in full, including endpoint, prefix, encryption mode, health, and reported usage.
flui backup destination show <dest-id>flui backup destination show <dest-id> --jsonflui 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.
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.
flui backup destination set-cost <dest-id> 1.606flui backup destination set-cost <dest-id> --list-priceflui 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.
flui backup destination delete <dest-id>flui backup destination delete <dest-id> --yesflui 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 createdoes not create a policy. It prints which command to use and exits. Create policies withflui 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.
flui backup policy listflui backup policy list --cluster <cluster-id>flui backup policy list --jsonflui 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.
flui backup policy show <policy-id>flui backup policy show <policy-id> --jsonflui 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.
flui backup policy delete <policy-id>flui backup policy delete <policy-id> --yesflui 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.
flui backup policy pause <policy-id>flui backup policy resume <id>
Turns a paused policy’s schedule back on.
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.
flui backup job run --policy <policy-id>flui backup job list
Lists the backup jobs for a cluster. --cluster (cluster ID) is
required.
flui backup job list --cluster <cluster-id>flui backup job list --cluster <cluster-id> --jsonflui backup job show <id>
Shows one job: its policy, status, start and completion times, bytes transferred, and error message if it failed.
flui backup job show <job-id>flui backup job show <job-id> --jsonflui backup restore
Shows the history of restores. You start a restore with the command that fits what you are restoring:
- a database, to a moment, into a new database:
flui db pitr-restore; - a volume, whole or file by file:
flui app backup restore; - the applications of a lost cluster:
flui cluster rebuild, and those of a lost control clusterflui cluster rebuild-control.
flui backup restore list
Lists restore jobs, with status, target kind, and target cluster.
flui backup restore listflui backup restore list --jsonflui backup restore show <id>
Shows one restore job: status, source artifact and destination, target, timing, and error message if it failed.
flui backup restore show <restore-id>flui backup restore show <restore-id> --jsonflui backup restore preview
Shows what a backup holds in its storage (objects and bytes) before you restore it. Both flags are required.
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.
flui app backup create my-app -D <dest-id>flui app backup create my-app -D <dest-id> --volume uploads --no-wait| Flag | Effect |
|---|---|
-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. |
--pause | Stop the application for the length of the copy, so a volume a database is writing to is copied at rest. |
--allow-inconsistent | Copy it while a database writes anyway. The copy may not restore cleanly. |
--no-wait | Return 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.
flui app backup list my-appflui app backup list my-app -o jsonflui app backup browse <name> <backup> [path]
Lists a folder inside a snapshot, read-only. Use it to find the
paths to give restore --path.
flui app backup browse my-app 3f2a91c0flui app backup browse my-app 3f2a91c0 uploads/2026flui 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.
flui app backup restore my-app 3f2a91c0flui app backup restore my-app 3f2a91c0 --swapflui app backup restore my-app 3f2a91c0 --to my-app-copy --swapflui app backup restore my-app 3f2a91c0 --path uploads/report.pdf --path configflui app backup restore my-app 3f2a91c0 --path uploads --into restored-uploads| Flag | Effect |
|---|---|
--swap | Switch 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, --yes | Do 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.
flui app backup delete my-app 3f2a91c0flui app backup delete my-app 3f2a91c0 --yesflui 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.
flui app backup before-deploy my-appflui app backup before-deploy my-app --requiredflui app backup before-deploy my-app --off| Flag | Effect |
|---|---|
--required | Fail the deploy when the backup before it cannot be taken. Without it the deploy goes ahead and the failure is logged. |
--off | Stop 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.
flui app backup skip my-app --note "rebuilt from source, nothing to keep"flui app backup skip my-app --undoflui 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.
flui backup platform initflui backup platform init --out /Volumes/usb/flui-recovery.age| Flag | Default | Effect |
|---|---|---|
--policy <id> | none | Platform backup policy to register the recipient on. |
--heartbeat-url <url> | none | Dead-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.age | Where to write the recovery copy. |
--passphrase <s> | none | Your vault passphrase, checked against the vault. Prompted if omitted. |
--rotate | off | Replace 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. |
--force | off | Overwrite an existing file at --out. |
--json | off | Print {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.
flui backup platform downloadflui backup platform download --job <backup-job-id> --out ./rebuild-input| Flag | Effect |
|---|---|
--job <id> | The backup to fetch. Defaults to the newest. |
--out <dir> | Where to write. Defaults to ./flui-platform-backup-<job>. |
--force | Overwrite files already in --out. |
--json | Print 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.
flui backup platform restore --bundle keybundle.age --dump flui-pg.dump.gz.encflui backup platform restore --bundle keybundle.age --dump flui-pg.dump.gz.enc \ --identity ~/flui-default-platform-recovery.age| Flag | Effect |
|---|---|
--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. |
--force | Overwrite 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].
flui backup platform statusflui backup platform status --jsonflui 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.
flui backup velero uninstall --planflui backup velero uninstall production --yes| Flag | Effect |
|---|---|
--plan | Show what would be removed and change nothing. |
-y, --yes | Do not ask for confirmation. |
--no-wait | Start the removal and return its operation id. |