Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Conversation

@drewburchfield
Copy link

@drewburchfield drewburchfield commented Dec 7, 2025

Summary

Adds a security-hardened Docker deployment for running the --chats conversation browser as a persistent service.

Security features:

  • Network isolation via sidecar proxy pattern (app container has no internet access)
  • Read-only filesystem, all capabilities dropped, no privilege escalation
  • Non-root user with configurable UID for volume permissions
  • Health checks with auto-restart via autoheal
  • Memory limits to prevent resource exhaustion
  • Localhost-only port binding

Test plan

  • Build and run: docker-compose up -d --build
  • Verify dashboard loads at http://localhost:9876
  • Confirm network isolation: docker exec claude-chats-monitor ping google.com should fail
  • Test health check recovery by killing the node process

Summary by cubic

Adds a Docker-based deployment to run the --chats server as a persistent local service with strict network isolation. The server runs on localhost:9876 behind a proxy and is hardened for production use.

  • New Features

    • Compose stack with isolated app, localhost proxy, health checks with autoheal, and memory limits.
    • Hardened container: non-root user, read-only filesystem, dropped capabilities, and no-new-privileges.
    • Read-only mount of ~/.claude with configurable USER_ID to avoid permission issues.
  • Dependencies

    • Pin claude-code-templates to 1.28.3.
    • Pin willfarrell/autoheal to 1.2.0.
    • Pin alpine/socat to 1.8.0.3.

Written for commit 6b5f9f2. Summary will update automatically on new commits.

Add Docker deployment configuration specifically for running the --chats
conversation browser feature persistently.

Note: This setup uses network isolation which prevents other CLI features
(--agent, --command) that require downloading templates from the internet.
The chats server only needs local file access.

Security features:
- Network isolation via sidecar proxy pattern (app has NO internet access)
- Read-only filesystem prevents persistence of malicious changes
- All Linux capabilities dropped (CAP_DROP ALL)
- No privilege escalation (no-new-privileges:true)
- Non-root user execution (configurable UID)
- Health checks with autoheal for automatic recovery
- Memory limits to prevent resource exhaustion
- Localhost-only port binding (127.0.0.1:9876)

Architecture:
- claude-chats: Main app container (isolated network, no internet)
- proxy: socat container bridging localhost to isolated network
- autoheal: Monitors and restarts unhealthy containers

Files added:
- cli-tool/docker-chats-server/Dockerfile
- cli-tool/docker-chats-server/docker-compose.yml
- cli-tool/docker-chats-server/README.md
Addresses PR review feedback to ensure reproducible builds:
- willfarrell/autoheal:latest → willfarrell/autoheal:1.2.0
- alpine/socat:latest → alpine/socat:1.8.0.3
- claude-code-templates@latest → claude-code-templates@1.28.3
@vercel
Copy link

vercel bot commented Dec 7, 2025

@drewburchfield is attempting to deploy a commit to the Daniel Avila's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 3 files

Prompt for AI agents (all 1 issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="cli-tool/docker-chats-server/README.md">

<violation number="1" location="cli-tool/docker-chats-server/README.md:96">
P2: The `curl` command is not available in the `claude-chats-monitor` container since it was intentionally excluded for security (see Dockerfile). Consider using the existing healthcheck approach with node&#39;s fetch, e.g.:
```bash
docker exec claude-chats-monitor node -e &quot;fetch(&#39;http://localhost:9876/api/conversations&#39;).then(r =&gt; console.log(&#39;Status:&#39;, r.status))&quot;
```</violation>
</file>

Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR

The health check tests `http://localhost:9876/api/conversations`. If failing:
```bash
# Check if the app is responding
docker exec claude-chats-monitor curl -s http://localhost:9876/api/conversations | head
Copy link

@cubic-dev-ai cubic-dev-ai bot Dec 7, 2025

Choose a reason for hiding this comment

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

P2: The curl command is not available in the claude-chats-monitor container since it was intentionally excluded for security (see Dockerfile). Consider using the existing healthcheck approach with node's fetch, e.g.:

docker exec claude-chats-monitor node -e "fetch('http://localhost:9876/api/conversations').then(r => console.log('Status:', r.status))"
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At cli-tool/docker-chats-server/README.md, line 96:

<comment>The `curl` command is not available in the `claude-chats-monitor` container since it was intentionally excluded for security (see Dockerfile). Consider using the existing healthcheck approach with node&#39;s fetch, e.g.:
```bash
docker exec claude-chats-monitor node -e &quot;fetch(&#39;http://localhost:9876/api/conversations&#39;).then(r =&gt; console.log(&#39;Status:&#39;, r.status))&quot;
```</comment>

<file context>
@@ -0,0 +1,160 @@
+The health check tests `http://localhost:9876/api/conversations`. If failing:
+```bash
+# Check if the app is responding
+docker exec claude-chats-monitor curl -s http://localhost:9876/api/conversations | head
+```
+
</file context>
Suggested change
docker exec claude-chats-monitor curl -s http://localhost:9876/api/conversations | head
docker exec claude-chats-monitor node -e "fetch('http://localhost:9876/api/conversations').then(r => r.json()).then(d => console.log(JSON.stringify(d).slice(0,500)))"
Fix with Cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Morty Proxy This is a proxified and sanitized view of the page, visit original site.