add Dockerfile + deployment docs; make config dbPath optional

node:24-bookworm-slim image with git for the read-only vault endpoints,
non-root user with system-wide git safe.directory (mounted vaults are
usually owned by a host uid), /config + /data + /vaults mount
conventions baked in via BRAINDUMP_CONFIG/BRAINDUMP_DB, and an
/api/health healthcheck. README gains a Deployment section (mounts,
claude-sdk skill/auth requirements in-container, compose example,
reverse-proxy SSE buffering notes).

dbPath in the config file now defaults to ./braindump.sqlite instead of
being required — it was validated before the BRAINDUMP_DB env override
was applied, so the image's baked-in db path couldn't rescue a config
that omitted it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-19 02:44:06 +00:00
co-authored by Claude
parent 9d71692402
commit ec6c4e8df0
4 changed files with 90 additions and 1 deletions
+45
View File
@@ -26,6 +26,51 @@ Config is JSONC; path from `BRAINDUMP_CONFIG` (default `./config.jsonc`). `"${EN
There is **no auth** — put it behind an authenticating reverse proxy. CORS origins are configurable (`app://obsidian.md` is in the example for Obsidian plugins).
## Deployment (Docker)
```sh
docker build -t braindump .
```
The image expects three mounts (paths inside the container are up to you; these match the defaults baked into the image via `BRAINDUMP_CONFIG=/config/config.jsonc` and `BRAINDUMP_DB=/data/braindump.sqlite`):
| Mount | Purpose |
|---|---|
| `/config/config.jsonc` | your config — point `vaults[].path` at the container-side vault paths |
| `/data` | persistent volume for the SQLite db |
| `/vaults/...` | your vault(s), read-write |
Backend-specific requirements:
- **`claude-sdk`**: pass `ANTHROPIC_API_KEY`, and mount the brain-dump skill into the container user's home so the SDK's skill loading finds it: `-v ~/.claude/skills/brain-dump:/home/braindump/.claude/skills/brain-dump:ro`.
- **`openai-compat`**: mount the skill file wherever `skillPath` in your config points (e.g. `/config/SKILL.md`), and pass any `${ENV_VAR}` referenced by the config (e.g. `OPENROUTER_API_KEY`).
Example `compose.yaml`:
```yaml
services:
braindump:
build: . # or image: gitea.codinget.me/codinget/braindump
ports: ["3000:3000"]
environment:
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
volumes:
- ./config.jsonc:/config/config.jsonc:ro
- braindump-data:/data
- ~/git/brain:/vaults/brain
- ~/.claude/skills/brain-dump:/home/braindump/.claude/skills/brain-dump:ro
volumes:
braindump-data:
```
with the corresponding config using container paths: `"vaults": [{ "name": "brain", "path": "/vaults/brain" }]` and `"skillPath": "/home/braindump/.claude/skills/brain-dump/SKILL.md"`.
Notes:
- The container runs as a non-root `braindump` user; git `safe.directory` is pre-configured system-wide so the read-only git endpoints work on vaults owned by your host uid. Vault *writes* need the mounted vault to be writable by the container user (`chmod`/`chown` or a matching uid via `user:`).
- The healthcheck and config default both use port 3000; if you change the port, change both (`PORT` env works too, and overrides the config).
- **Reverse proxy + SSE**: disable response buffering for `/api/sessions/*/messages` (nginx: `proxy_buffering off;`, or honor the `X-Accel-Buffering: no` pattern) and raise/disable the proxy read timeout for long turns — heartbeat comments are sent every ~15s to keep the connection alive. This is also where your auth goes.
## API
Base path `/api`. Errors are `{"ok":false,"error":"<code>"}`.