Skip to content

fix: make Docker quickstart work out of the box + robust SQLite fallback#236

Merged
hoangsonww merged 2 commits into
hoangsonww:masterfrom
loris-av:fix/docker-quickstart-and-sqlite-fallback
Jul 17, 2026
Merged

fix: make Docker quickstart work out of the box + robust SQLite fallback#236
hoangsonww merged 2 commits into
hoangsonww:masterfrom
loris-av:fix/docker-quickstart-and-sqlite-fallback

Conversation

@loris-av

Copy link
Copy Markdown
Contributor

Summary

Two independent, low-risk fixes (one commit each), both first-run failures for new users:

1. fix(docker) — the documented Docker/Podman quickstart fails out of the box

Following the README/INSTALL/SETUP/DEPLOYMENT/wiki Docker instructions currently fails in one of two ways:

  • Crash-loop: the server writes its SQLite data dir under ~/.claude/agent-dashboard by default, but the recommended ~/.claude bind mount is read-only → Error: ENOENT: no such file or directory, mkdir '/root/.claude/agent-dashboard', container restarts forever.
  • Connection reset: since the loopback-default hardening (GHSA-gr74-4xfh-6jw9) the server binds 127.0.0.1, but a container's loopback is a separate namespace the published port cannot reach, so docker run -p 4820:4820 / Compose return curl: (56) Recv failure: Connection reset by peer.

Fix (baked into the image so both Compose and plain docker run work as-is):

  • Dockerfile: ENV DASHBOARD_DATA_DIR=/app/data (writable volume) + ENV DASHBOARD_HOST=0.0.0.0 (bind inside the container).
  • docker-compose.yml: publish the host port on 127.0.0.1 only → dashboard stays local-only by default. The trust boundary moves from the in-container bind to the host port publish, preserving the GHSA loopback posture (no LAN exposure without an explicit opt-in).

Docs updated to match across all surfaces (README + VN/CN/KO, INSTALL, SETUP, DEPLOYMENT, wiki): plain-run examples use -p 127.0.0.1:4820:4820, prose explains the image defaults and how to opt into LAN exposure (publish on 0.0.0.0 + set DASHBOARD_TOKEN). Wiki gains a "Local-only by default" callout with zh/vi translations and the required sw.js cache bump + asset ?v= bump.

2. fix(server) — server crashes at startup when better-sqlite3's native addon is broken

require("better-sqlite3") only loads its JS; the native addon is resolved lazily on the first new Database(...). When the prebuilt binary is missing or ABI-mismatched (e.g. node_modules installed under a different Node version), require() succeeds but construction throws — and the real new Database(DB_PATH) in server/db.js runs outside the try/catch, so the process dies at startup instead of using the intended node:sqlite fallback.

Fix: probe better-sqlite3 with a throwaway in-memory handle right after require, so a broken native binary falls back to node:sqlite now rather than crashing later.

Testing

  • npm run test:server652/652 pass.
  • Verified the container quickstart end-to-end with the versioned config only (fresh docker compose up -d --build): /api/health → 200, UI → 200, no restart loop, and the LAN IP is unreachable (local-only confirmed).
  • Verified the SQLite fallback by simulating a broken native binary: server/db.js now loads via node:sqlite without crashing.
  • Wiki i18n coverage verified (the new callout's strong + paragraph resolve to zh and vi); prettier --check clean on all touched files.

Note: the client snapshot tests (screens.snapshot.test.tsx) fail locally only due to a locale/timezone difference (1:00:00 PM vs 13:00:00) unrelated to these changes — no client source was touched, so I intentionally did not regenerate those baselines.

🤖 Generated with Claude Code

loris-av and others added 2 commits July 16, 2026 16:23
The documented Docker/Podman quickstart failed on first run in two ways:

- The server writes its SQLite data dir under ~/.claude/agent-dashboard by
  default, but the recommended ~/.claude bind mount is read-only, so the
  container crash-looped on `ENOENT: mkdir '/root/.claude/agent-dashboard'`.
- Since the loopback-default hardening (GHSA-gr74-4xfh-6jw9) the server binds
  127.0.0.1, but a container's loopback is a separate namespace the published
  port cannot reach, so `docker run -p 4820:4820` returned connection-reset.

Fix in the image so both Compose and plain `docker run` work as-is:

- Dockerfile: bake DASHBOARD_DATA_DIR=/app/data (writable volume) and
  DASHBOARD_HOST=0.0.0.0 (bind inside the container).
- docker-compose.yml: publish the host port on 127.0.0.1 only, keeping the
  dashboard local-only by default — the trust boundary moves from the
  in-container bind to the host port publish, preserving the GHSA posture.

Docs updated to match (README + VN/CN/KO, INSTALL, SETUP, DEPLOYMENT, wiki):
plain-run examples use `-p 127.0.0.1:4820:4820`, prose explains the image
defaults and how to opt into LAN exposure (publish on 0.0.0.0 + DASHBOARD_TOKEN).
Wiki gains a "Local-only by default" callout with zh/vi translations and the
required cache bump.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…don fails

better-sqlite3's require() only loads its JS; the native addon is resolved
lazily on the first `new Database(...)`. When the prebuilt binary is missing or
ABI-mismatched (e.g. installed for a different Node version), require() succeeds
but construction throws — and the real `new Database(DB_PATH)` runs outside the
try/catch, so the server crashed at startup instead of using the intended
node:sqlite fallback.

Probe better-sqlite3 with a throwaway in-memory handle right after require, so a
broken native binary falls back to node:sqlite now rather than crashing later.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@loris-av
loris-av requested a review from hoangsonww as a code owner July 16, 2026 14:24
@github-actions github-actions Bot added bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed question Further information is requested labels Jul 16, 2026
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown

✅ All contributors have signed the CLA. Thank you!
Posted by the CLA Assistant Lite bot.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances container security and reliability by ensuring the agent dashboard is local-only by default. It updates the Dockerfile, docker-compose.yml, and documentation across multiple languages to bind the published container port to the host's loopback interface (127.0.0.1) instead of exposing it on all interfaces. Inside the container, the application binds to 0.0.0.0 (DASHBOARD_HOST) to allow port forwarding, and the SQLite data directory is redirected to a writable volume (/app/data). Additionally, server/db.js is updated to eagerly probe the better-sqlite3 native addon, ensuring a graceful fallback to node:sqlite if there is an ABI mismatch. I have no further feedback to provide as the changes are well-implemented and documented.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@loris-av

Copy link
Copy Markdown
Contributor Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Jul 16, 2026
@hoangsonww
hoangsonww merged commit e980b29 into hoangsonww:master Jul 17, 2026
11 of 12 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 17, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed question Further information is requested

Projects

Development

Successfully merging this pull request may close these issues.

2 participants