mirror of
https://github.com/MeshCore-Beacon/beacon-docs.git
synced 2026-10-23 01:51:24 +00:00
* docs: move design and API contract into docs/ * docs: add releases and versioning page * docs: add configuration reference for server and web * docs: add reverse proxy page * docs: add upgrading page * docs: add operations page and move backup and profiling docs * docs: add getting packets in and security pages * docs: add troubleshooting page * docs(api): fold admin, activity, route and summary notes into the contract * docs(deploy): add type 2 split deployment, finish the beacon rename, ignore secrets * docs: rewrite README as the front door and share the contributor workflow * docs: remove em dashes from prose and config comments * docs: apply review fixes to type 2, upgrading, troubleshooting and first-run notes * docs: fix upgrade order, restore steps, type 2 setup and contract details from review * docs: keep the gitignore to deployment secrets and runtime state
116 lines
4.9 KiB
Markdown
116 lines
4.9 KiB
Markdown
# Day-to-day operations
|
|
|
|
Everything here assumes the all-in-one Docker stack. The commands translate to the split
|
|
deployment by running them on the server host.
|
|
|
|
## Checking it is healthy
|
|
|
|
Beacon has no health endpoint yet. Use these instead:
|
|
|
|
- `docker compose ps` shows every container `Up`. `db` and `redis` have health checks; `app`
|
|
waits for both before it starts.
|
|
- `curl -s https://<your-domain>/api/v1/brokers` lists each MQTT broker with its connection
|
|
status. A broker that never connects is a URL or credentials problem; see
|
|
[Getting packets in](getting-packets-in.md).
|
|
- Open `wss://<your-domain>/ws` in a WebSocket client. The first frame is `hello`.
|
|
- `docker compose logs -f app` shows a `connected` line per broker. Individual packets are
|
|
not logged at the default `info` level, so a quiet log after that is normal; use the
|
|
observers endpoint or the web app to see traffic.
|
|
|
|
## Logs
|
|
|
|
Logs go to stderr and Docker collects them. Docker's default `json-file` driver does not
|
|
rotate, so on a long-running host set a cap, either in `/etc/docker/daemon.json` for every
|
|
container or per service in `docker-compose.yml`:
|
|
|
|
```yaml
|
|
logging:
|
|
driver: json-file
|
|
options: { max-size: "50m", max-file: "5" }
|
|
```
|
|
|
|
Set `log.level` (`debug`, `info`,
|
|
`warn`, `error`; default `info`) and `log.format` (`text` or `json`) in `config.yaml`, or
|
|
override them with `LOG_LEVEL` and `LOG_FORMAT`. Invalid values stop startup.
|
|
|
|
Every record has a `component`. Ingest records add the broker name; HTTP completion records
|
|
add the validated client address, route, status and duration. Query strings and WebSocket
|
|
hello payloads are never logged. Expected ingest skips and routine WebSocket lifecycle events
|
|
are at debug level.
|
|
|
|
```bash
|
|
docker compose logs -f app # the API and ingest
|
|
docker compose logs -f caddy # the proxy
|
|
```
|
|
|
|
Caddy also writes a JSON access log to `data/Caddy/logs/access.json`, which the fail2ban rules
|
|
in [`app_config/fail2ban/`](../app_config/fail2ban/README.md) read.
|
|
|
|
## Where the data lives
|
|
|
|
Everything persistent is under `data/` next to `docker-compose.yml`:
|
|
|
|
- `data/postgres/` is the database. Deleting it deletes all history.
|
|
- `data/redis/` is the cache. It can be removed while the stack is down; Beacon rebuilds it.
|
|
- `data/Caddy/data/` holds TLS certificates. Deleting it means a new certificate request on
|
|
the next start, which counts against Let's Encrypt rate limits.
|
|
- `data/app/config.yaml` and `.env` are your configuration. Keep copies of both somewhere
|
|
else; no backup below includes `.env`.
|
|
|
|
## Retention
|
|
|
|
Everything below is a duration in `config.yaml`. Shorten them if disk is tight, lengthen them
|
|
if you want more history.
|
|
|
|
| Setting | Default | What it covers |
|
|
|---|---|---|
|
|
| `packets.retention` | `168h` (7 days) | Packets, observations and channel messages |
|
|
| `analytics.rollup_retention` | `2160h` (90 days) | Hourly stats rollups. Also the longest window the stats endpoints accept |
|
|
| `telemetry.retention` | `744h` (31 days) | Observer telemetry snapshots |
|
|
| `routes.retention` | `336h` (14 days) | Known routes, counted from when a route was last seen |
|
|
| `nodes.delete_after` | `720h` (30 days) | Nodes not heard from |
|
|
| `observers.delete_after` | off | Observers not heard from. Opt in by setting a duration |
|
|
|
|
Historical stats read the hourly rollups, not raw packets. Each UTC hour is rolled about 95
|
|
minutes after it closes, and packet cleanup holds back up to 24 hours of raw rows until their
|
|
hours are rolled, so raw data lives a little longer than `packets.retention` says. An hour
|
|
whose raw rows were deleted first is reported as partial, with no values.
|
|
|
|
## Backing up
|
|
|
|
Two options.
|
|
|
|
**A plain `pg_dump`** from the host, which is enough for most operators:
|
|
|
|
```bash
|
|
docker compose exec -T db pg_dump -U beacon -d beacon -Fc > beacon-$(date +%F).dump
|
|
```
|
|
|
|
Keep `data/app/config.yaml` and `.env` with it. The dump holds message data and anything you
|
|
have decrypted, so treat it as private.
|
|
|
|
**The admin backup endpoint** produces an archive of the database and the saved
|
|
`config.yaml`, with a manifest and checksums, and a command-line tool that verifies it. It is
|
|
off by default and needs the admin key. See [Backup and export](backup-export.md).
|
|
|
|
## Restoring
|
|
|
|
Restore into an empty database, never over live data. With the stack running and the app
|
|
stopped, drop and recreate the database, load the dump, and only then start the app:
|
|
|
|
```bash
|
|
docker compose stop app
|
|
docker compose exec -T db psql -U beacon -d postgres -c 'DROP DATABASE beacon;' -c 'CREATE DATABASE beacon;' \
|
|
&& docker compose exec -T db pg_restore -U beacon -d beacon < beacon-YYYY-MM-DD.dump \
|
|
&& docker compose start app
|
|
```
|
|
|
|
If `pg_restore` reports errors the app is not started; read them before trying again.
|
|
|
|
A 1.x dump cannot be restored into 2.0.0; the server refuses the old schema. See
|
|
[Upgrading](upgrading.md#upgrading-to-200-from-1x).
|
|
|
|
## CPU profiling
|
|
|
|
Bounded CPU captures on a running instance are described in [Profiling](profiling.md).
|