Files
NestQuest/api/README.md
T
overseerandClaude Opus 5.5 89a10edc38 Add Litestream continuous backup of the SQLite database
Task 47b27ccb: a litestream sidecar (litestream/litestream:0.5.17) in
deploy/compose.yaml mounts the nestquest-db volume and replicates
/var/lib/nestquest/nestquest.db over SFTP to the Synology NAS
(10.60.1.50, /homes/Joshua/nestquest-backups), outside the Docker host.
deploy/litestream.yml holds no secrets: the NAS host key is pinned and
the dedicated SFTP private key is mounted read-only from the
git-ignored deploy/litestream_key. api/README.md documents what runs,
where it writes, key setup, and a high-level restore.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 08:15:53 -04:00

72 lines
3.3 KiB
Markdown

# NestQuest API
Standalone FastAPI service owning the NestQuest database (Feature 16).
Served with ``uvicorn --factory api.app:create_app``; configuration is
environment-supplied (``api/config.py``) and every variable is required.
## Runtime dependencies
``api/requirements.txt`` is the API deployable's OWN dependency
manifest (fastapi, uvicorn, pyjwt[crypto], httpx) — deliberately kept
out of the integration's ``pyproject.toml`` dev group, which exists only
so the monorepo test venv can run the API tests.
## Container deployment (scaffold)
The image is built from the repository ROOT context (the API loads the
bundled domain core from ``custom_components/nestquest/core/`` by file
location, so both trees must be in the build context):
docker build -t nestquest-api:latest .
Run it with compose — the SQLite file lives on the named volume
``nestquest-db`` so recreating the container keeps household data:
cp deploy/.env.example deploy/.env # then fill in real values
docker compose -f deploy/compose.yaml up -d --build
``deploy/.env`` is git-ignored and supplies the secrets (panel service
token, Authentik OIDC settings); ``NESTQUEST_DB_PATH`` is fixed to
``/var/lib/nestquest/nestquest.db`` by compose.
The published port binds ``NESTQUEST_BIND_ADDRESS`` from
``deploy/.env`` and defaults to ``127.0.0.1`` (localhost only). In
production TLS is terminated by the shared Traefik reverse proxy,
which serves ``https://nestquest.cubecraftlabs.com`` (Let's Encrypt,
auto-renewed, HTTP redirected to HTTPS) and forwards to the API box
on port 8080 — so on that box set ``NESTQUEST_BIND_ADDRESS`` to its
LAN address (``10.60.1.14``). Traefik only allows
``/api/v1/panel`` from the Home Assistant host. Network separation
and the full restore runbook are later Feature 17 tasks.
## Continuous backup (Litestream)
Compose also runs a ``litestream`` sidecar
(``litestream/litestream:0.5.17``, config ``deploy/litestream.yml``).
It mounts the same ``nestquest-db`` volume and continuously replicates
``/var/lib/nestquest/nestquest.db`` over SFTP to the Synology NAS
``CubeCraft-SRVR1`` (``joshua@10.60.1.50``), directory
``/volume1/homes/Joshua/nestquest-backups`` (``/homes/Joshua/...`` in
the NAS's chrooted SFTP view) — so the backup is outside the Docker
host and its volume. A snapshot is taken daily and a week of
snapshots plus incremental changes is retained; the NAS host key is
pinned in the config.
The SFTP login uses a dedicated keypair that lives only on the API
box and is git-ignored. Create it once, before ``up``:
ssh-keygen -t ed25519 -N "" -C nestquest-litestream -f deploy/litestream_key
then append ``restrict `` + the contents of ``deploy/litestream_key.pub``
to ``joshua@10.60.1.50:~/.ssh/authorized_keys``. Compose mounts the
private key read-only at ``/etc/litestream/sftp_key``.
Check replication with
``docker compose -f deploy/compose.yaml logs litestream`` or
``docker compose -f deploy/compose.yaml exec litestream litestream ltx /var/lib/nestquest/nestquest.db``.
To restore (high level): stop the ``api`` service, run
``litestream restore -config /etc/litestream.yml -o <new path>
/var/lib/nestquest/nestquest.db`` from a litestream container with the
same mounts, verify the restored file, move it into place on the
volume (removing any stale ``-wal``/``-shm`` files), and start ``api``
again.