mirror of
https://github.com/MeshCore-Beacon/beacon-docs.git
synced 2026-10-23 01:51:24 +00:00
129 lines
6.2 KiB
Markdown
129 lines
6.2 KiB
Markdown
# Backup and export
|
|
|
|
Beacon exports its PostgreSQL database and saved `config.yaml` as a private, versioned
|
|
`.tar.gz`, either with the standalone `beacon-backup` command or an opt-in admin download.
|
|
`beacon-backup -verify` checks an archive offline. There is no import, scheduling or remote
|
|
storage.
|
|
|
|
## Archive format 1
|
|
|
|
Exactly three regular files:
|
|
|
|
- `manifest.json`: format and exporter version, creation time, payload sizes and SHA-256
|
|
hashes, and the exclusions below.
|
|
- `database.sql`: one consistent `pg_dump` snapshot (schema, data, migration journal),
|
|
without ownership, ACLs or tablespaces so it restores under any role.
|
|
- `config.yaml`: the saved file byte-for-byte, read just before the snapshot. Avoid config
|
|
edits during an export.
|
|
|
|
**It is sensitive and unencrypted** (keys, message data); keep it private. It is not a full
|
|
recovery package: `.env` and environment variables, `borderFile` and TLS files, runtime-only
|
|
changes, PostgreSQL roles and cluster settings, Redis and deployment files are not included.
|
|
|
|
## Requirements and limits
|
|
|
|
- Keep the MeshMapper API key in `MESHMAPPER_API_KEY`, with `meshmapper.api_key` empty or
|
|
omitted in the saved YAML. Both CLI exports and admin downloads refuse a nonempty saved
|
|
MeshMapper key because the YAML is included verbatim. Environment secrets remain excluded;
|
|
preserve them separately for recovery. See [MeshMapper API key](configuration.md#meshmapper-api-key).
|
|
- `pg_dump` must be in the **same runtime** as the exporter (the CLI's environment, or the
|
|
server's PATH for the download), with a major version at least as new as the database's. A client on
|
|
the Docker host or in another container doesn't count.
|
|
- The Docker image ships the PostgreSQL 16 client. Its Alpine 3.19 base has no 17/18
|
|
packages, so a newer database needs a different runtime, not just `POSTGRES_CLIENT_MAJOR`.
|
|
- The temp directory (`TMPDIR`) needs about twice the SQL limit free. A small tmpfs won't do.
|
|
- The output filesystem must support hard links (used to publish atomically). Existing
|
|
destinations, symlinks included, are never replaced. Files are 0600 and staging dirs 0700;
|
|
on Windows, restrict the directory ACLs yourself.
|
|
|
|
| Limit | Default |
|
|
| --- | --- |
|
|
| Timeout | 10 min (`-timeout`) |
|
|
| Uncompressed SQL | 1 GiB (`-max-bytes`, up to 1 TiB) |
|
|
| Saved YAML / manifest | 1 MiB / 64 KiB |
|
|
| Compressed archive (verify) | SQL limit + 1% + 2 MiB |
|
|
| Lock wait | 5 s |
|
|
|
|
Failures, timeouts and interrupts clean up and publish nothing. A SIGKILL or power loss can
|
|
leave a private staging dir: `.beacon-backup-*` next to the CLI output, or
|
|
`beacon-download-*` in the server's temp dir, which Beacon sweeps on its next start.
|
|
|
|
## CLI export
|
|
|
|
In a beacon-server clone:
|
|
|
|
```sh
|
|
go build ./cmd/beacon-backup
|
|
./beacon-backup -config /private/config.yaml -output /private/beacon-20260913.tar.gz
|
|
```
|
|
|
|
Connection comes only from the standard libpq environment (`PGHOST`, `PGPORT`,
|
|
`PGDATABASE`, `PGUSER`, TLS settings); `PGDATABASE` is required. Keep the password in a 0600
|
|
`PGPASSFILE` or a service file. The command ignores `.env` and `POSTGRES_DSN`, runs no
|
|
migrations, and never prints `pg_dump` stderr since it can leak private data. If it fails,
|
|
check the client version, privileges, connection settings and free space.
|
|
|
|
## Download API
|
|
|
|
`GET /api/v1/admin/backup` streams a fresh archive. Enable it with `backup.enabled: true` and
|
|
the admin bearer key, then restart. Send the key only in the `Authorization` header over
|
|
HTTPS; the endpoint takes no query or body. Leave it off on public previews.
|
|
|
|
At startup Beacon checks `pg_dump --version` against the server. If that or another
|
|
prerequisite fails, it logs why and disables only backup; fix it and restart.
|
|
|
|
**Connection.** The download uses `POSTGRES_DSN`, which must be a single-host `postgres://`
|
|
URL with an explicit user and database. TLS options, `passfile`, `connect_timeout`,
|
|
`application_name`, `target_session_attrs` and `options` are passed through; `pool_*`
|
|
options are dropped; supported `PG*` env defaults apply under the URL. Keyword DSNs,
|
|
services, multiple hosts, unknown or duplicate options, protocol-negotiation settings and
|
|
the `PGSERVICE`, `PGSERVICEFILE`, `PGSSLNEGOTIATION`, `PG{MIN,MAX}PROTOCOLVERSION` and `PGTZ`
|
|
env vars are rejected. Use the CLI for those setups. Prefer `sslmode=verify-full` for remote
|
|
databases. Credentials go to a 0600 service file in staging, never into process arguments,
|
|
logs or errors.
|
|
|
|
**Behaviour.** One export at a time. Disconnecting cancels it, and the transfer has a
|
|
10-minute write deadline. Responses are `no-store`. A failed export sends no partial archive
|
|
and logs a sanitized reason.
|
|
|
|
| Status | Meaning |
|
|
| --- | --- |
|
|
| 400 | Query string or body sent |
|
|
| 401 | Missing or invalid key |
|
|
| 409 | Another export is running |
|
|
| 500 | Export failed |
|
|
| 503 | Backup unavailable, no admin key, or shutting down |
|
|
| 504 | Timed out |
|
|
| 507 | SQL size limit exceeded |
|
|
|
|
## Verify
|
|
|
|
```sh
|
|
./beacon-backup -verify /private/beacon-20260913.tar.gz
|
|
```
|
|
|
|
Reads the file without extracting, running SQL or connecting to anything, so it needs no
|
|
config, `pg_dump` or credentials. `-max-bytes` and `-timeout` apply. It requires exactly the
|
|
three members as 0600 regular files with USTAR headers (size-only PAX allowed for SQL over
|
|
8 GiB). It rejects duplicates, links, devices, extra metadata, truncated or concatenated
|
|
streams, and unknown or duplicate manifest keys. Sizes and SHA-256 hashes must match.
|
|
|
|
Exit 0 means structure and checksums passed. Errors don't include payload, manifest values
|
|
or the path. The manifest is unsigned, so a pass does **not** prove authenticity, safe SQL or
|
|
that the dump restores.
|
|
|
|
## Restore
|
|
|
|
Only restore trusted bundles, because a dump can run arbitrary SQL. Verify, extract
|
|
privately, and load into a **new, empty database** on a compatible PostgreSQL with the
|
|
needed extensions:
|
|
|
|
```sh
|
|
psql -X --set ON_ERROR_STOP=on --single-transaction --file database.sql
|
|
```
|
|
|
|
Check the migration journal and some records, review the config, and restore external
|
|
secrets and files before pointing a new Beacon at it. Never test an export by restoring over
|
|
live data. See [pg_dump](https://www.postgresql.org/docs/16/app-pgdump.html) and
|
|
[libpq environment](https://www.postgresql.org/docs/16/libpq-envars.html).
|