Skip to content

feat: add Dockerfile for production deployment#82

Open
rhlsthrm wants to merge 1 commit into
iamlukethedev:mainfrom
rhlsthrm:add-dockerfile
Open

feat: add Dockerfile for production deployment#82
rhlsthrm wants to merge 1 commit into
iamlukethedev:mainfrom
rhlsthrm:add-dockerfile

Conversation

@rhlsthrm
Copy link
Copy Markdown

@rhlsthrm rhlsthrm commented Mar 30, 2026

Summary

Adds a multi-stage Dockerfile for containerized production deployments of Claw3D.

Motivation

Running Claw3D alongside other Docker services (e.g., on a server that already runs OpenClaw + supporting infrastructure via docker-compose) is much easier with a Dockerfile. Currently users must install Node.js on the host and run npm run dev or npm run build && npm start directly.

Details

Three-stage build for minimal image size:

  1. depsnpm ci with lock file for reproducible installs
  2. builder — Next.js production build
  3. runner — only the built app, public assets, custom server, and node_modules

Supports runtime gateway configuration via CLAW3D_GATEWAY_URL env var without requiring a rebuild. Default port is 3000, configurable via PORT env var.

Example docker-compose usage

claw3d:
  build: ./claw3d
  network_mode: host
  environment:
    - PORT=3000
    - CLAW3D_GATEWAY_URL=ws://127.0.0.1:18789
    - CLAW3D_GATEWAY_TOKEN=${OPENCLAW_GATEWAY_TOKEN}
  restart: unless-stopped

Test plan

  • docker build -t claw3d . succeeds
  • docker run -e CLAW3D_GATEWAY_URL=ws://localhost:18789 -p 3000:3000 claw3d starts and serves UI
  • WebSocket proxy to gateway works from container

Note

Low Risk
Low risk because it only adds container packaging/build configuration and does not change runtime application logic. Primary risk is build/startup mismatches in the container (missing files/env defaults).

Overview
Adds a new Dockerfile that enables containerized production deployments via a three-stage build (depsbuilderrunner).

The image builds the Next.js app with telemetry disabled and a default NEXT_PUBLIC_GATEWAY_URL, then runs the existing custom server via node server/index.js on port 3000.

Written by Cursor Bugbot for commit cd660d4. This will update automatically on new commits. Configure here.

Multi-stage Docker build for containerized deployments:
- Stage 1 (deps): npm ci with lock file
- Stage 2 (builder): Next.js production build
- Stage 3 (runner): minimal image with custom server

Supports runtime gateway configuration via CLAW3D_GATEWAY_URL
env var without requiring a rebuild.
@rhlsthrm rhlsthrm requested a review from iamlukethedev as a code owner March 30, 2026 18:10
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment thread Dockerfile
FROM node:20-slim AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing .dockerignore lets COPY . . overwrite clean deps

High Severity

There is no .dockerignore file in the repository. The COPY . . in the builder stage runs after COPY --from=deps /app/node_modules ./node_modules, so if a node_modules/ directory exists on the build host, it overwrites the clean, reproducible install from the deps stage. This defeats the purpose of the multi-stage build and npm ci. It also sends the entire repository (including .git/, test files, .env files with potential secrets) into the build context and image layers.

Fix in Cursor Fix in Web

Comment thread Dockerfile
FROM node:20-slim AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --ignore-scripts
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Production image includes all devDependencies unnecessarily

Medium Severity

The deps stage runs npm ci --ignore-scripts without --omit=dev, so devDependencies (Playwright, jsdom, Vitest, ESLint, etc.) are installed. These flow through the builder stage into the runner stage via the node_modules copy. This contradicts the stated goal of "minimal image size" from the three-stage build and adds significant bloat plus unnecessary attack surface to the production image.

Additional Locations (1)
Fix in Cursor Fix in Web

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.

2 participants