better-sqlite3@12.11.1 ships prebuilt binaries for ABI 127/137/141/147 only;
Node 20 is ABI 115, so prebuild-install falls back to node-gyp, which fails on
node:20-slim for lack of python3/make/g++.
Add the toolchain to the builder stage, and in the runtime stage install, use
and purge it inside a single layer so the final image ships no compiler.
Unpinned `pnpm@latest` in the Dockerfile made fresh builds non-reproducible:
`latest` now resolves to pnpm 11, but the committed lockfile targets pnpm 10, so
`pnpm install --frozen-lockfile` fails with ERR_PNPM_LOCKFILE_CONFIG_MISMATCH on
a clean host. Pin pnpm to 10.34.3 across the Dockerfile, the `packageManager`
field, and the release workflow; pin Node to 20 (LTS) via `.nvmrc` and `engines`
so Docker, CI, and from-source builds all use the same tested toolchain.
Also corrects the docs: the lockfile is v9.0 (requires pnpm 10, not "pnpm 8+"),
and "Node 20+" implied untested newer majors were supported.
Three changes to cut deploy time:
1. deploy.sh: Pi and VM deploy concurrently (wall time = max, not sum)
2. deploy.sh: Build cache capped at 2GB instead of nuked after 24h,
so pnpm install layer is reused between deploys
3. Dockerfile: runtime stage uses --prod (skip devDeps). Moved tsx
from devDependencies to dependencies since it's used in CMD.
Redesign deployment as a single docker-compose with Backspace, Caddy
(auto-HTTPS), and LiveKit (voice/video) using hybrid networking:
Backspace+Caddy on isolated bridge, LiveKit on host mode for WebRTC.
- Add install.sh: interactive installer that handles Docker setup,
domain/DNS verification, secret generation, LiveKit config, and
deployment with health-check wait
- Add Caddyfile: static reverse proxy config using Caddy env vars,
routes /livekit/* to host-mode LiveKit via host.docker.internal
- Rewrite docker-compose.yml: all-in-one with profiles (voice),
no external volumes/networks, bind mount ./data for visibility
- Fix livekit.ts: use LIVEKIT_URL env var directly instead of
Host-header derivation that made the env var dead code
- Fix Dockerfile: health check reads $PORT dynamically
- Update .env.example: add DOMAIN, COMPOSE_PROFILES documentation
- Update .gitignore: add livekit.yaml (contains secrets)
- docker-compose: use external volume/network with backspace naming
- deploy.sh: add --remote/-r flag for off-network deploys, update remote path
- Dockerfile: update DB_PATH to backspace.db