Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/de/self-hosted/install/linux-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Jeder Service sollte `running` oder `healthy` zeigen. Folg dem **Schritt 4 — D

Bevor du User auf die URL zeigst, machen dir drei Haken später das Leben leichter:

- **Backups.** Richt dein bestehendes Snapshot-Tooling auf `db-data` und das Object-Store-Volume — siehe [Backups und Restore](/de/self-hosted/operate/backups-and-restore).
- **Backups.** `tale backup` snapshottet die Daten-Volumes — Blobs eingeschlossen — ins `backups`-Volume; richte dein Off-Host-Tooling auf dieses Volume plus Projekt-Workspace und `.env` — siehe [Backups und Restore](/de/self-hosted/operate/backups-and-restore).
- **Logs.** Tale loggt auf stdout. Hat der Host journald, trägt `journalctl -u docker` alles; sonst pipe zu deinem Aggregator.
- **Metriken.** Setze `METRICS_BEARER_TOKEN` in `.env` und scrap `/metrics` aus deinem Prometheus — siehe [Observability-Konfiguration](/de/self-hosted/configuration/observability-config).

Expand Down
19 changes: 12 additions & 7 deletions docs/de/self-hosted/operate/backups-and-restore.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ Der Architektur-Kontext lebt in [Container-Architektur](/de/self-hosted/operate/

## Was ein Snapshot enthält

| Volume | Enthält |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `db-data` | Postgres — der Anwendungsspeicher (Agents, Runs, das Audit-Log) und der Wissens-Korpus (Dokument-Chunks, Embeddings, gecrawlte Seiten) |
| `convex-data` | Org-Config, Anbieter-Secrets, hochgeladenes Branding |
| `caddy-data`, `caddy-config` | TLS-Zertifikate und Proxy-State |
| Volume | Enthält |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `db-data` | Postgres — der Anwendungsspeicher (Agents, Runs, das Audit-Log) und der Wissens-Korpus (Dokument-Chunks, Embeddings, gecrawlte Seiten) |
| `convex-data` | Org-Config, Anbieter-Secrets, hochgeladenes Branding |
| `object-store-data` | Der Blob-Store — hochgeladene Dateien, Chat-Anhänge, Audio, generierte Medien —, solange der Deployment-Default der mitgelieferte Objektspeicher ist |
| `caddy-data`, `caddy-config` | TLS-Zertifikate und Proxy-State |

Jeder Snapshot ist ein Verzeichnis mit einem Namen wie `20260611-142530-deploy` im `backups`-Volume des Projekts: ein `.tar.gz` pro Volume, je ein `.sha256`-Sidecar und ein zuletzt geschriebenes `manifest.json`. Ein Verzeichnis ohne Manifest ist ein unvollständiger Snapshot — er taucht nie in Listings auf und lässt sich nie wiederherstellen. Der Snapshot lässt `object-store-data` bewusst aus — den Blob-Store mit hochgeladenen Dateien und generierten Medien —, sodass diese Blobs ihre eigene Off-Host-Erfassung brauchen, neben den zwei Dingen, die ganz außerhalb der Volumes leben: dem Projekt-Workspace (das Verzeichnis mit `tale.json`) und `.env`.
Jeder Snapshot ist ein Verzeichnis mit einem Namen wie `20260611-142530-deploy` im `backups`-Volume des Projekts: ein `.tar.gz` pro Volume, je ein `.sha256`-Sidecar und ein zuletzt geschriebenes `manifest.json`. Ein Verzeichnis ohne Manifest ist ein unvollständiger Snapshot — er taucht nie in Listings auf und lässt sich nie wiederherstellen. Zwei Dinge leben ganz außerhalb der Volumes und brauchen ihren eigenen Platz in deinem Off-Host-Job: der Projekt-Workspace (das Verzeichnis mit `tale.json`) und `.env`.

Blobs folgen dem Objektspeicher. Mit dem mitgelieferten `object-store` — dem Default — erfasst der Snapshot `object-store-data` wie jedes andere Volume, und sein Archiv ist so groß wie alles, was je hochgeladen wurde: Während des Tars pausiert der Store, Uploads und Downloads stehen also so lange still. In zwei Fällen liegen Blobs außerhalb des Snapshots, und beide sagt das Backup an, statt sie zu verschweigen. Zeigt der Deployment-Default auf ein externes S3 (`default/object-storage/connection.json` nennt nicht mehr den mitgelieferten Store), liegt im lokalen Volume nichts, was die App liest: Das Backup überspringt das Volume, und `tale backup` druckt eine einzeilige Notiz mit Endpoint und Bucket — dieses Bucket sicherst du mit deinem eigenen S3-Tooling. Eine Organisation, die unter **Einstellungen > Datenresidenz** ihren eigenen Bucket mitbringt, schreibt ebenfalls nie ins lokale Volume; die Notiz nennt die Organisation, und kein Snapshot kann diese Blobs enthalten.

## Wann Snapshots genommen werden

`tale deploy` snapshotet vor seinem ersten mutierenden Schritt, wann immer der Deploy Daten ändern kann: Die Zielversion weicht von der laufenden ab oder ein Host-Config-Push (`--override` / `--override-all`) ist angefordert. Während jedes Volume getart wird, sind die Container, die es nutzen, für ein paar Sekunden pausiert, damit das Archiv crash-konsistent ist — eine Live-Kopie eines laufenden Postgres-Verzeichnisses ist nicht wiederherstellbar.
`tale deploy` snapshotet vor seinem ersten mutierenden Schritt, wann immer der Deploy Daten ändern kann: Die Zielversion weicht von der laufenden ab oder ein Host-Config-Push (`--override` / `--override-all`) ist angefordert. Während jedes Volume getart wird, pausieren die Container, die es nutzen, für die Dauer des Tars — Sekunden bei Datenbank- und Config-Volumes, beim Blob-Volume so lange, wie der Store groß ist —, damit das Archiv crash-konsistent ist: Eine Live-Kopie eines laufenden Postgres-Verzeichnisses ist nicht wiederherstellbar.

Ein gescheiterter Snapshot bricht den Deploy ab. `--skip-backup` übersteuert das auf `tale deploy` — dann sind deine eigenen externen Backups der einzige Recovery-Pfad, und genau deshalb loggt das Flag eine laute Warnung.

Expand Down Expand Up @@ -62,6 +65,8 @@ tale deploy --stop

Das Redeploy der passenden Version ist Teil des Restores, kein optionales Extra: Der Snapshot hat die Daten exakt so erfasst, wie diese Plattform-Version sie hinterlassen hat, und ein neueres Binary würde sofort wieder seine Migrationen darauf laufen lassen. Die Restore-Ausgabe druckt die exakte Version aus dem Manifest des Snapshots.

Ein Snapshot aus der Zeit, bevor Blobs erfasst wurden, oder von einem Deployment, dessen Blobs in einem externen S3 liegen, hat kein `object-store-data`-Archiv. `tale restore` listet solche Snapshots als `without blobs`, sagt es vor der Bestätigung noch einmal und lässt das Blob-Volume unangetastet, während es alles andere wiederherstellt — die Blobs bleiben genau so, wie sie auf dem Host sind.

## Restore-Drill

Lauf den Drill vierteljährlich auf einem Nicht-Produktions-Host. Der Drill ist nicht „existiert ein Snapshot" — er ist „kann ein frischer Host aus der Off-Host-Kopie des `backups`-Volumes, dem Projekt-Workspace und `.env` in unter einer Stunde wiederaufgebaut werden". Die Fehler-Modi, die der Drill fängt: ein Off-Host-Job, der den Workspace nie erfasst hat, und eine veraltete `.env`, die nicht mehr zu den Anforderungen des aktuellen Binarys passt.
Expand Down
2 changes: 1 addition & 1 deletion docs/de/self-hosted/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Diese Volumes überleben ein `docker compose down`:
- `caddy-data`, `caddy-config` — TLS-Zertifikate und Proxy-State.
- `backups` — prüfsummengesicherte Volume-Snapshots, geschrieben von `tale backup` und automatisch vor migrierenden Deploys; [Backups und Restore](/de/self-hosted/operate/backups-and-restore) ist die Übung.

Alles andere ist ephemer. Container lassen sich ohne Datenverlust ersetzen, solange die Volumes überleben. Ein Vorbehalt, den du verinnerlichen solltest: `tale backup` snapshottet `db-data`, `convex-data` und die Caddy-Volumes, aber **nicht** `object-store-data` die Blobs brauchen ihre eigene Off-Host-Sicherung, behandelt in [Backups und Restore](/de/self-hosted/operate/backups-and-restore).
Alles andere ist ephemer. Container lassen sich ohne Datenverlust ersetzen, solange die Volumes überleben. `tale backup` snapshottet die Daten-Volumes oben — `object-store-data` eingeschlossen, solange die Blobs im mitgelieferten Objektspeicher liegen. Blobs in einem externen S3-Bucket, ob umgebogener Deployment-Default oder eigener Bucket einer Organisation, sicherst du selbst, und das Backup sagt dir das; [Backups und Restore](/de/self-hosted/operate/backups-and-restore) hat die Liste und die Übung.

## Provider-Secrets und die SOPS-Schicht

Expand Down
2 changes: 1 addition & 1 deletion docs/en/self-hosted/install/linux-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Every service should be `running` or `healthy`. Walk through **Step 4 — Create

Before pointing users at the URL, three hooks make life easier later:

- **Backups.** Point your existing snapshot tooling at `db-data` and the object store volume — see [Backups and restore](/self-hosted/operate/backups-and-restore).
- **Backups.** `tale backup` snapshots the data volumes — blobs included — into the `backups` volume; point your off-host tooling at that volume plus the project workspace and `.env` — see [Backups and restore](/self-hosted/operate/backups-and-restore).
- **Logs.** Tale logs to stdout. If the host has journald, `journalctl -u docker` carries everything; otherwise pipe to your aggregator.
- **Metrics.** Set `METRICS_BEARER_TOKEN` in `.env` and scrape `/metrics` from your Prometheus — see [Observability config](/self-hosted/configuration/observability-config).

Expand Down
19 changes: 12 additions & 7 deletions docs/en/self-hosted/operate/backups-and-restore.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ The architecture context lives in [Container architecture](/self-hosted/operate/

## What a snapshot contains

| Volume | Holds |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `db-data` | Postgres — the application store (agents, runs, the audit log) and the knowledge corpus (document chunks, embeddings, crawled pages) |
| `convex-data` | Org config, provider secrets, uploaded branding |
| `caddy-data`, `caddy-config` | TLS certificates and proxy state |
| Volume | Holds |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `db-data` | Postgres — the application store (agents, runs, the audit log) and the knowledge corpus (document chunks, embeddings, crawled pages) |
| `convex-data` | Org config, provider secrets, uploaded branding |
| `object-store-data` | The blob store — uploaded files, chat attachments, audio, generated media — whenever the deployment default is the bundled object store |
| `caddy-data`, `caddy-config` | TLS certificates and proxy state |

Each snapshot is a directory named like `20260611-142530-deploy` inside the project's `backups` volume: one `.tar.gz` per volume, a `.sha256` sidecar each, and a `manifest.json` written last. A directory without a manifest is an incomplete snapshot — it never shows up in listings and can never be restored. The snapshot deliberately skips `object-store-data` — the blob store holding uploaded files and generated media — so those blobs need their own off-host capture, alongside the two things that live outside the volumes entirely: the project workspace (the directory holding `tale.json`) and `.env`.
Each snapshot is a directory named like `20260611-142530-deploy` inside the project's `backups` volume: one `.tar.gz` per volume, a `.sha256` sidecar each, and a `manifest.json` written last. A directory without a manifest is an incomplete snapshot — it never shows up in listings and can never be restored. Two things live outside the volumes entirely and need their own place in your off-host job: the project workspace (the directory holding `tale.json`) and `.env`.

Blobs follow the object store. With the bundled `object-store` — the default — `object-store-data` is captured like every other volume, and its archive is as large as everything ever uploaded: the store is paused while it is tarred, so uploads and downloads stall for that long. Two cases put blobs outside the snapshot, and both are announced rather than silent. A deployment default repointed at an external S3 (`default/object-storage/connection.json` no longer naming the bundled store) leaves the local volume with nothing the app reads, so the volume is skipped and `tale backup` prints a one-line notice with the endpoint and bucket — that bucket's backup runs under your own S3 tooling. An organization that brings its own bucket under **Settings > Data residency** never writes to the local volume either; the notice names the organization, and no snapshot can contain those blobs.

## When snapshots are taken

`tale deploy` snapshots before its first mutating step whenever the deploy can change data: the target version differs from the running one, or a host-config push (`--override` / `--override-all`) is requested. While each volume is tarred, the containers using it are paused for a few seconds so the archive is crash-consistent a live copy of a running Postgres directory is not restorable.
`tale deploy` snapshots before its first mutating step whenever the deploy can change data: the target version differs from the running one, or a host-config push (`--override` / `--override-all`) is requested. While each volume is tarred, the containers using it are paused for the duration — seconds for the database and config volumes, as long as the store is large for the blob volume — so the archive is crash-consistent: a live copy of a running Postgres directory is not restorable.

A failed snapshot aborts the deploy. `--skip-backup` overrides that on `tale deploy`, which leaves your own external backups as the only recovery path — the flag logs a loud warning for exactly that reason.

Expand Down Expand Up @@ -62,6 +65,8 @@ tale deploy --stop

The redeploy of the matching version is part of the restore, not an optional extra: the snapshot captured the data exactly as that platform version left it, and a newer binary would immediately re-run its migrations against it. The restore output prints the exact version recorded in the snapshot's manifest.

A snapshot taken before blobs were captured, or on a deployment whose blobs live in external S3, has no `object-store-data` archive. `tale restore` lists such snapshots as `without blobs`, says so again before asking for confirmation, and leaves the blob volume untouched while it restores everything else — the blobs stay exactly as they are on the host.

## Restore drill

Run the drill quarterly on a non-production host. The drill is not "does a snapshot exist" — it is "can a fresh host be rebuilt from the off-host copy of the `backups` volume, the project workspace, and `.env` in under an hour." The failure modes the drill catches: an off-host job that never captured the workspace, and a stale `.env` that no longer matches the current binary's requirements.
Expand Down
2 changes: 1 addition & 1 deletion docs/en/self-hosted/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ These volumes survive a `docker compose down`:
- `caddy-data`, `caddy-config` — TLS certificates and proxy state.
- `backups` — checksummed volume snapshots written by `tale backup` and automatically before migrating deploys; [Backups and restore](/self-hosted/operate/backups-and-restore) is the drill.

Everything else is ephemeral. Containers can be replaced without data loss as long as the volumes survive. One caveat worth internalising: `tale backup` snapshots `db-data`, `convex-data`, and the Caddy volumes, but **not** `object-store-data` — the blobs need their own off-host capture, covered in [Backups and restore](/self-hosted/operate/backups-and-restore).
Everything else is ephemeral. Containers can be replaced without data loss as long as the volumes survive. `tale backup` snapshots the data volumes above — `object-store-data` included, as long as the blobs live in the bundled object store. Blobs in an external S3 bucket, whether a repointed deployment default or an organization's own bucket, are yours to back up, and the backup says so; [Backups and restore](/self-hosted/operate/backups-and-restore) has the list and the drill.

## Provider secrets and the SOPS layer

Expand Down
2 changes: 1 addition & 1 deletion docs/fr/self-hosted/install/linux-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Chaque service devrait être `running` ou `healthy`. Parcours **Étape 4 — Cr

Avant de pointer des utilisateurs sur l'URL, trois crochets te facilitent la vie plus tard :

- **Sauvegardes.** Pointe ton outillage de snapshot existant vers `db-data` et le volume du stockage objet — voir [Sauvegardes et restauration](/fr/self-hosted/operate/backups-and-restore).
- **Sauvegardes.** `tale backup` snapshotte les volumes de données — blobs compris — dans le volume `backups` ; pointe ton outillage hors-hôte vers ce volume plus le workspace du projet et `.env` — voir [Sauvegardes et restauration](/fr/self-hosted/operate/backups-and-restore).
- **Logs.** Tale logue sur stdout. Si l'hôte a journald, `journalctl -u docker` transporte tout ; sinon, pipe vers ton agrégateur.
- **Métriques.** Règle `METRICS_BEARER_TOKEN` dans `.env` et scrape `/metrics` depuis ton Prometheus — voir [Configuration de l'observabilité](/fr/self-hosted/configuration/observability-config).

Expand Down
Loading
Loading