Skip to content

feat: Phase 14/15 — Cloudflare Containers setup for graph-server#70

Draft
cdxker wants to merge 15 commits intomainfrom
tickets/phase-14-15-containers
Draft

feat: Phase 14/15 — Cloudflare Containers setup for graph-server#70
cdxker wants to merge 15 commits intomainfrom
tickets/phase-14-15-containers

Conversation

@cdxker
Copy link
Owner

@cdxker cdxker commented Mar 13, 2026

Summary

  • Consolidate pnpm lockfiles to workspace root, removing per-package lockfiles
  • Add Cloudflare Containers infrastructure: Dockerfile, .dockerignore, container entry point (container-entry.ts), and CF Worker entry (container-worker.ts)
  • Configure wrangler.toml with staging containers environment and Durable Object migration (new_sqlite_classes)
  • Expose staging Postgres on 0.0.0.0:5433 via docker-compose.yaml for container access
  • Install @cloudflare/containers and updated workers-types
  • Update Phase 15 ticket docs with credentials, migration field, and deploy caveats

Test plan

  • Verify pnpm install works correctly from workspace root
  • Build the Docker image from graph-server/Dockerfile and confirm it starts
  • Deploy to staging with wrangler deploy and verify container worker routes
  • Confirm Durable Object migration applies cleanly on free plan
  • Validate staging Postgres is reachable from container at host.docker.internal:5433

🤖 Generated with Claude Code


Note

High Risk
Exposes a Postgres instance on 0.0.0.0:5433 and commits database credentials in docker-compose.yaml, which increases the risk of unintended external access or credential leakage.

Overview
Adds a new postgres-staging service to docker-compose.yaml, with its own persistent volume, explicit port publish (0.0.0.0:5433:5432), and listen_addresses=* so it can be reached externally (e.g., by remote containers).

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

cdxker and others added 12 commits March 12, 2026 21:29
Staged files:
- graph-frontend/pnpm-lock.yaml (deleted)
- graph-server/pnpm-lock.yaml (deleted)
- pnpm-lock.yaml (updated root lockfile)
…kers-types

Staged files:
- graph-server/package.json
Staged files:
- graph-server/src/server/container-entry.ts
…rver

Staged files:
- graph-server/Dockerfile
- graph-server/.dockerignore
…ntry

Staged files:
- graph-server/src/server/container-worker.ts
- graph-server/tsconfig.json
…tainers env

Staged files:
- graph-server/wrangler.toml
… caveats

- Replace hardcoded DB credentials with env var references ($STAGING_DATABASE_URL)
- Add validation note for new_classes vs new_sqlite_classes in wrangler migration
- Flag missing production worker.ts entrypoint as known issue
- Document non-atomic deploy caveat for CF Containers beta

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ckets complete

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…n free plan

Cloudflare error 10097 confirmed: free plan requires new_sqlite_classes
instead of new_classes for Durable Object namespace creation.

Staged files:
- graph-server/wrangler.toml
…correct docker build context

Run wrangler from repo root with --config so docker build context
includes pnpm-lock.yaml and pnpm-workspace.yaml at repo root.

Staged files:
- graph-server/wrangler.toml
@cdxker
Copy link
Owner Author

cdxker commented Mar 14, 2026

bugbot run

Copy link

@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.

restart: unless-stopped
environment:
POSTGRES_USER: everysong_staging
POSTGRES_PASSWORD: "kX9#mQ2$vL7nR4wB"
Copy link

Choose a reason for hiding this comment

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

Hardcoded staging database password committed to repo

High Severity

A non-trivial password (kX9#mQ2$vL7nR4wB) for the staging Postgres database is hardcoded in docker-compose.yaml, which is committed to version control. Combined with the service binding to all interfaces (0.0.0.0:5433) and the ticket docs referencing a public IP (216.38.137.154:5433), this exposes the staging database credentials to anyone with repo access. The existing dev postgres service uses obvious default credentials, but the staging password appears to be a real secret. It would be better managed via environment variable substitution or a .env file (which is already gitignored).

Fix in Cursor Fix in Web

restart: unless-stopped
environment:
POSTGRES_USER: everysong_staging
POSTGRES_PASSWORD: "kX9#mQ2$vL7nR4wB"
Copy link

Choose a reason for hiding this comment

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

Dollar sign in password triggers variable interpolation

High Severity

Docker Compose performs variable interpolation on $ signs in YAML values. The password "kX9#mQ2$vL7nR4wB" contains $vL7nR4wB, which Compose will interpret as a reference to the environment variable vL7nR4wB. Since that variable almost certainly isn't set, it silently resolves to an empty string, making the effective password kX9#mQ2 instead of the intended value. This will cause any application using the full password string to fail to connect. The $ needs to be escaped as $$.

Fix in Cursor Fix in Web

cdxker added 3 commits March 13, 2026 19:05
…ld-graph changes

Staged files:
- graph-server/Dockerfile
- graph-server/src/graph/build-graph.ts
- tickets/TICKETS.md
- tickets/phase16-bugfix-pr70/01-Triage-HardcodedStagingCredentials.md
- tickets/phase16-bugfix-pr70/01-Triage-DockerComposePasswordInterpolation.md
Staged files:\ngraph-frontend/.pages/_worker.js/_chunks/ssr-renderer.mjs
graph-frontend/.pages/_worker.js/_libs/@radix-ui/react-accessible-icon+[...].mjs
graph-frontend/.pages/_worker.js/_libs/@radix-ui/react-dismissable-layer+[...].mjs
graph-frontend/.pages/_worker.js/_libs/@radix-ui/react-navigation-menu+[...].mjs
graph-frontend/.pages/_worker.js/_libs/@radix-ui/react-one-time-password-field+[...].mjs
graph-frontend/.pages/_worker.js/_libs/@radix-ui/react-password-toggle-field+[...].mjs
graph-frontend/.pages/_worker.js/_libs/@radix-ui/react-use-callback-ref+[...].mjs
graph-frontend/.pages/_worker.js/_libs/@radix-ui/react-use-controllable-state+[...].mjs
graph-frontend/.pages/_worker.js/_libs/@radix-ui/react-use-effect-event+[...].mjs
graph-frontend/.pages/_worker.js/_libs/@radix-ui/react-use-escape-keydown+[...].mjs
graph-frontend/.pages/_worker.js/_libs/@radix-ui/react-use-is-hydrated+[...].mjs
graph-frontend/.pages/_worker.js/_libs/@radix-ui/react-use-layout-effect+[...].mjs
graph-frontend/.pages/_worker.js/_libs/@radix-ui/react-visually-hidden+[...].mjs
graph-frontend/.pages/_worker.js/_libs/aria-hidden.mjs
graph-frontend/.pages/_worker.js/_libs/base-ui__react.mjs
graph-frontend/.pages/_worker.js/_libs/base-ui__utils.mjs
graph-frontend/.pages/_worker.js/_libs/class-variance-authority.mjs
graph-frontend/.pages/_worker.js/_libs/clsx.mjs
graph-frontend/.pages/_worker.js/_libs/cookie-es.mjs
graph-frontend/.pages/_worker.js/_libs/croner.mjs
graph-frontend/.pages/_worker.js/_libs/crossws.mjs
graph-frontend/.pages/_worker.js/_libs/date-fns.mjs
graph-frontend/.pages/_worker.js/_libs/date-fns__tz.mjs
graph-frontend/.pages/_worker.js/_libs/detect-node-es.mjs
graph-frontend/.pages/_worker.js/_libs/floating-ui__core.mjs
graph-frontend/.pages/_worker.js/_libs/floating-ui__dom.mjs
graph-frontend/.pages/_worker.js/_libs/floating-ui__react-dom.mjs
graph-frontend/.pages/_worker.js/_libs/floating-ui__utils.mjs
graph-frontend/.pages/_worker.js/_libs/get-nonce.mjs
graph-frontend/.pages/_worker.js/_libs/graphology-utils.mjs
graph-frontend/.pages/_worker.js/_libs/graphology.mjs
graph-frontend/.pages/_worker.js/_libs/h3.mjs
graph-frontend/.pages/_worker.js/_libs/hookable.mjs
graph-frontend/.pages/_worker.js/_libs/isbot.mjs
graph-frontend/.pages/_worker.js/_libs/lucide-react.mjs
graph-frontend/.pages/_worker.js/_libs/ohash.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__number.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__primitive.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-accordion.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-alert-dialog.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-arrow.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-aspect-ratio.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-avatar.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-checkbox.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-collapsible.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-collection.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-compose-refs.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-context-menu.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-context.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-dialog.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-direction.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-dropdown-menu.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-focus-guards.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-focus-scope.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-form.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-hover-card.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-id.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-label.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-menu.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-menubar.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-popover.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-popper.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-portal.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-presence.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-primitive.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-progress.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-radio-group.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-roving-focus.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-scroll-area.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-select.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-separator.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-slider.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-slot.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-switch.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-tabs.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-toast.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-toggle-group.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-toggle.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-toolbar.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-tooltip.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-use-previous.mjs
graph-frontend/.pages/_worker.js/_libs/radix-ui__react-use-size.mjs
graph-frontend/.pages/_worker.js/_libs/react-day-picker.mjs
graph-frontend/.pages/_worker.js/_libs/react-dom.mjs
graph-frontend/.pages/_worker.js/_libs/react-remove-scroll-bar.mjs
graph-frontend/.pages/_worker.js/_libs/react-remove-scroll.mjs
graph-frontend/.pages/_worker.js/_libs/react-sigma__core.mjs
graph-frontend/.pages/_worker.js/_libs/react-style-singleton.mjs
graph-frontend/.pages/_worker.js/_libs/react.mjs
graph-frontend/.pages/_worker.js/_libs/reselect.mjs
graph-frontend/.pages/_worker.js/_libs/rou3.mjs
graph-frontend/.pages/_worker.js/_libs/seroval-plugins.mjs
graph-frontend/.pages/_worker.js/_libs/seroval.mjs
graph-frontend/.pages/_worker.js/_libs/sigma.mjs
graph-frontend/.pages/_worker.js/_libs/srvx.mjs
graph-frontend/.pages/_worker.js/_libs/tabbable.mjs
graph-frontend/.pages/_worker.js/_libs/tailwind-merge.mjs
graph-frontend/.pages/_worker.js/_libs/tanstack__history.mjs
graph-frontend/.pages/_worker.js/_libs/tanstack__query-core.mjs
graph-frontend/.pages/_worker.js/_libs/tanstack__react-query.mjs
graph-frontend/.pages/_worker.js/_libs/tanstack__react-router.mjs
graph-frontend/.pages/_worker.js/_libs/tanstack__react-store.mjs
graph-frontend/.pages/_worker.js/_libs/tanstack__router-core.mjs
graph-frontend/.pages/_worker.js/_libs/tanstack__store.mjs
graph-frontend/.pages/_worker.js/_libs/tiny-invariant.mjs
graph-frontend/.pages/_worker.js/_libs/tiny-warning.mjs
graph-frontend/.pages/_worker.js/_libs/tslib.mjs
graph-frontend/.pages/_worker.js/_libs/ufo.mjs
graph-frontend/.pages/_worker.js/_libs/unctx.mjs
graph-frontend/.pages/_worker.js/_libs/unstorage.mjs
graph-frontend/.pages/_worker.js/_libs/use-callback-ref.mjs
graph-frontend/.pages/_worker.js/_libs/use-sidecar.mjs
graph-frontend/.pages/_worker.js/_libs/use-sync-external-store.mjs
graph-frontend/.pages/_worker.js/_ssr/Graph-QklLfi8X.mjs
graph-frontend/.pages/_worker.js/_ssr/index-D91a9fRr.mjs
graph-frontend/.pages/_worker.js/_ssr/index.mjs
graph-frontend/.pages/_worker.js/_ssr/router-Dz7Ytvrw.mjs
graph-frontend/.pages/_worker.js/_ssr/start-HYkvq4Ni.mjs
graph-frontend/.pages/_worker.js/_ssr/user._username-CxFOcS5Y.mjs
graph-frontend/.pages/_worker.js/_tanstack-start-manifest_v-DCeuAEmU.mjs
graph-frontend/.pages/_worker.js/index.js
graph-frontend/.pages/_worker.js/index.mjs
graph-frontend/.pages/assets/Graph-B1nuGzxy.js
graph-frontend/.pages/assets/index-236c62ad.esm-DAaW5_Mr.js
graph-frontend/.pages/assets/index-Zi7xv0Tc.js
graph-frontend/.pages/assets/main-WOqfbknq.js
graph-frontend/.pages/assets/react-sigma_core.esm.min-j0wB-B0q.js
graph-frontend/.pages/assets/sigma-rendering.esm-B04X1yUO.js
graph-frontend/.pages/assets/styles-Ct55cw4F.css
graph-frontend/.pages/assets/user-DEqMBSbC.css
graph-frontend/.pages/assets/user._username-BSoxVw1L.js
graph-frontend/.pages/favicon.ico
graph-frontend/.pages/robots.txt
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