# Back up and restore Falak

> Back up the Falak control plane with falak-ctl — database, Fleet CA, storage and .env — schedule, encrypt, copy to S3, restore, or move to a new host.

Source: https://falak.sh/docs/operations/backup-restore/

This page covers backing up **Falak itself**. Your apps' databases have their own [database backups](/docs/databases/backups/).

Every agent trusts only Falak's Fleet CA, and the CA's private key is stored in the database encrypted with `APP_KEY`. A backup is only useful with its **database and `.env` together**. Lose either and every server must be re-enrolled. Keep copies **off the host**.

## Take a backup

```bash
sudo falak-ctl backup
sudo falak-ctl backup --label before-migration
```

```text title="Expected output"
==> backup falak-backup-20260928T031500Z
  ✓ database (12M)
  ✓ volumes: falak-ca (Fleet CA), app-storage, caddy-data
```

The file is `/opt/falak/backups/falak-backup-[-label].tar.gz`. It contains:

| Item | Contents |
|---|---|
| `db.dump` | `pg_dump -Fc` of the Falak database (including the encrypted Fleet CA key) |
| `falak-ca.tar.gz` | The Fleet CA certificate and the agent API certificate |
| `app-storage.tar.gz` | Build artifacts and app files |
| `caddy-data.tar.gz` | ACME account and certificates |
| `env`, `custom.env` | Your settings and secrets (`APP_KEY`) |
| `manifest` | Falak version, time, host, domain |

## Schedule daily backups

```bash
echo '15 3 * * * root /usr/local/bin/falak-ctl backup --quiet' | sudo tee /etc/cron.d/falak-backup
```

The newest 14 backups are kept (`FALAK_BACKUP_KEEP` in `.env`).

## Encrypt backups

Set a passphrase in `/opt/falak/.env`:

```dotenv
FALAK_BACKUP_PASSPHRASE=a-long-random-passphrase
```

Backups are then written as `*.tar.gz.enc` (AES-256-CBC, `openssl enc -pbkdf2`). A restore needs the same passphrase. Store it somewhere other than the host.

## Copy backups off the host (S3)

Set these in `/opt/falak/.env` to upload each backup to an S3-compatible bucket (path-style URLs, `curl --aws-sigv4`):

| Variable | Example / default |
|---|---|
| `FALAK_BACKUP_S3_ENDPOINT` | `https://s3.eu-central-1.amazonaws.com` |
| `FALAK_BACKUP_S3_BUCKET` | `acme-falak-backups` |
| `FALAK_BACKUP_S3_REGION` | default `us-east-1` |
| `FALAK_BACKUP_S3_ACCESS_KEY`, `FALAK_BACKUP_S3_SECRET_KEY` | credentials |
| `FALAK_BACKUP_S3_PREFIX` | default `falak` |

The local copy is kept even when an upload fails.

## Restore

```bash
sudo falak-ctl restore /opt/falak/backups/falak-backup-20260101T030000Z.tar.gz --yes
sudo falak-ctl restore falak-backup-20260101T030000Z.tar.gz --yes          # a file in backups/
sudo falak-ctl restore falak-backup-….tar.gz --yes --keep-env              # keep the current .env
```

The restore stops the app and edge, restores the database, volumes and `.env`/`custom.env`, starts the stack, and recreates services whose config files changed. The `falak-ca` volume is re-synced by the edge within 3 seconds.

Use `--keep-env` only when the current `.env` has the **same `APP_KEY`** as the backup. Otherwise the Fleet CA key cannot be decrypted and agents go offline.

## Move Falak to a new host

1. Take a backup on the old host and copy it to the new host.
2. Install Falak on the new host with the **same `--domain`** (use `--skip-dns-check` while DNS still points at the old host).
3. Restore: `sudo falak-ctl restore <file> --yes`. This brings back the old `.env`, including `APP_KEY`.
4. Point DNS for the panel, `agents.` and `grafana.` at the new host.

Agents keep working without re-enrolling, because the Fleet CA and `APP_KEY` came with the backup.

## Troubleshooting

| Symptom | Fix |
|---|---|
| Agents go offline after a restore | The restored `.env`/`APP_KEY` must belong to the same backup as the database. |
| `… is encrypted: set FALAK_BACKUP_PASSPHRASE` | Put the passphrase in `.env` (or the environment) and retry. |
| `… is not a Falak backup (db.dump/env missing)` | The file is incomplete or not a falak-ctl backup. |

## Next steps
