Skip to content

🤖 fix: ship the analytics worker in the Docker image and smoke-test it on image PRs - #5627

Merged
ThomasK33 merged 3 commits into
mainfrom
fix/5603-docker-analytics-worker
Oct 4, 2026
Merged

ThomasK33 merged 3 commits into
mainfrom
fix/5603-docker-analytics-worker

Conversation

@ThomasK33

@ThomasK33 ThomasK33 commented Oct 4, 2026 •

Copy link
Copy Markdown
Member

Summary

The Docker server image now ships dist/runtime/analyticsWorker.js and the DuckDB native bindings it needs, so the analytics worker starts in Docker. Smoke / Docker now also runs on PRs that touch server image inputs, and it starts the shipped analytics worker instead of checking only /health.

Fixes #5603
Fixes #5605

Background

AnalyticsService starts analyticsWorker.js from the directory of the running server bundle. make build-docker-runtime never built that file, so every analytics request in the Docker image failed with Cannot find module '/app/dist/runtime/analyticsWorker.js'. /health does not start the worker (it starts lazily), and Smoke / Docker ran only in the merge queue, so nothing caught this.

The two issues share one PR on purpose: the new smoke step is the regression test for #5603, and this PR touches the Dockerfile, so its own CI run shows the new trigger.

Implementation

  1. Makefile: a new dist/runtime/analyticsWorker.js target bundles the worker with esbuild. @duckdb/* stays external because esbuild cannot bundle the native .node binding. verify-docker-runtime-artifacts now checks the file.
  2. Dockerfile: the runtime stage copies node_modules/@duckdb. The builder stage first deletes the musl bindings, because the runtime image is glibc (node:22-slim). detect-libc, which the bindings use, is already in the image for sharp.
  3. scripts/check-analytics-worker.cjs: starts a built worker, runs its init task (opens a DuckDB database through the native binding), then shuts it down. It exits nonzero on any worker error.
  4. .github/workflows/pr.yml:
    • A new docker path filter in changes lists everything the Dockerfile copies into the build stage (src/**, docs/**, package, lock and patch files, the Makefile, the copied scripts, the Vite entry files, public/**, static/**), plus Dockerfile, .dockerignore and pr.yml itself. A Dockerfile comment asks to keep the two lists in sync.
    • Smoke / Docker runs on pull_request when that filter matches. Merge queue and push behavior is unchanged.
    • The container test runs the check script inside the image: docker exec -i mux-test node - /app/dist/runtime/analyticsWorker.js < scripts/check-analytics-worker.cjs.

Decision (conservative option): ship the worker instead of disabling analytics in Docker. The image grows by about 75 MB (436 MB to 511 MB locally) for libduckdb.so.

Validation

I built the image from origin/main (before) and from this branch (after) with docker build, ran each container, started the worker with the check script, and called POST /api/analytics/getSummary with the container's auth token.

Before (origin/main)
$ curl /health
{"status":"ok"}
$ docker exec ws72-before ls dist/runtime
mcpIconDecode.js
server-bundle.js
tokenizer-encoding-cl100k_base.js
tokenizer-encoding-claude.js
tokenizer-encoding-o200k_base.js
tokenizer-encoding-p50k_base.js
tokenizer.worker.js
$ docker exec -i ws72-before node - /app/dist/runtime/analyticsWorker.js < scripts/check-analytics-worker.cjs
analytics worker error: Cannot find module '/app/dist/runtime/analyticsWorker.js'
exit=1

Server log after POST /api/analytics/getSummary (response: INTERNAL_SERVER_ERROR):

6:44.789PM dist/runtime/server-bundle.js:27 [AnalyticsService] Worker error { error: "Cannot find module '/app/dist/runtime/analyticsWorker.js'" }
6:44.791PM dist/runtime/server-bundle.js:27 ORPC /api/analytics/getSummary: Error: Cannot find module '/app/dist/runtime/analyticsWorker.js'
6:44.793PM dist/runtime/server-bundle.js:27 [AnalyticsService] Worker exited unexpectedly { code: 1 }
After (this branch)
$ curl /health
{"status":"ok"}
$ docker exec ws72-after ls dist/runtime node_modules/@duckdb
/app/dist/runtime:
analyticsWorker.js
mcpIconDecode.js
server-bundle.js
tokenizer-encoding-cl100k_base.js
tokenizer-encoding-claude.js
tokenizer-encoding-o200k_base.js
tokenizer-encoding-p50k_base.js
tokenizer.worker.js

/app/node_modules/@duckdb:
node-api
node-bindings
node-bindings-linux-x64
$ docker exec -i ws72-after node - /app/dist/runtime/analyticsWorker.js < scripts/check-analytics-worker.cjs
[analytics-worker] Shutting down, closing DuckDB
analytics worker OK: /app/dist/runtime/analyticsWorker.js
exit=0
$ POST /api/analytics/getSummary
{"totalSpendUsd":0,"todaySpendUsd":0,"avgDailySpendUsd":0,"cacheHitRatio":0,"totalTokens":0,"totalResponses":0}
$ docker logs ws72-after | grep -i analytics
[analytics-worker] syncCheck: plan=noop, workspacesOnDisk=0, watermarksInDB=0 (21ms)

Smoke / Docker trigger:

Risks

Low. The change adds files to the image and a CI job to most code PRs. Smoke / Docker took about 4 minutes on this PR, in parallel with the other jobs. A new Dockerfile COPY input that is missing from the filter reaches the merge queue unchecked, as before.


Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-04T19:08:28.277682Z 7d4c07c New commits
🔒 Security Review ✅ Completed 2026-10-04T19:12:00.050463Z 7d4c07c New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7cf008df47

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/pr.yml Outdated
@ThomasK33

Copy link
Copy Markdown
Member Author

Readiness record:

  • Final commit: 7d4c07cf74484e9ac83e46332e9774a56a3314cb
  • CI: Required passed on this commit. Smoke / Docker ran on this commit and passed, and its log shows analytics worker OK: /app/dist/runtime/analyticsWorker.js.
  • Reviews: 5 of 6 assessments used (2 automatic normal reviews, 2 automatic security reviews, 1 final independent check). Findings went from 1 in round 1 (path filter too narrow, fixed) to 0 in round 2. Both security reviews had no findings.
  • Final independent check: READY.
  • Not verified: CI smoke-tests only the amd64 image. The arm64 release image gets the same glibc binding from bun.lock, but I did not run the worker check on arm64.
  • Decision: ready. Merging with --match-head-commit.

Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high

@ThomasK33
ThomasK33 added this pull request to the merge queue Oct 4, 2026
Merged via the queue into main with commit 12ead6f Oct 4, 2026
30 of 31 checks passed
@ThomasK33
ThomasK33 deleted the fix/5603-docker-analytics-worker branch October 4, 2026 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant