Skip to content

Add remote R2 bucket binding for local development#222

Open
nickscarabosio wants to merge 24 commits intocloudflare:mainfrom
nickscarabosio:main
Open

Add remote R2 bucket binding for local development#222
nickscarabosio wants to merge 24 commits intocloudflare:mainfrom
nickscarabosio:main

Conversation

@nickscarabosio
Copy link

Summary

  • Adds a second R2 bucket binding with remote: true to wrangler.jsonc, enabling R2 access during local development with wrangler dev --remote

Test plan

  • Verified deployment succeeds with updated config
  • Confirm wrangler dev --remote can access the moltbot-data R2 bucket locally

🤖 Generated with Claude Code

Nicholas Scarabosio and others added 24 commits February 9, 2026 12:11
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Enables the OpenClaw agent to query Gmail and Google Calendar remotely
via OAuth2 credentials passed as worker secrets. Includes scripts for
searching/reading/sending email and listing/creating calendar events.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The sandbox's startProcess does not inherit Dockerfile ENV vars, so
globally installed npm packages aren't found by require(). Add
NODE_PATH initialization directly in google-auth.js and as a
Dockerfile ENV for other contexts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace googleapis npm package with the gogcli binary, which is
OpenClaw's built-in Google Workspace skill. The startup script now
configures gogcli credentials and imports the refresh token from
env vars using the file-based keyring backend.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The sandbox SDK can have undefined exitCode for fast-exiting processes
like `test -f`, causing the sync to falsely report "no config file
found". Switch to ls + stdout parsing (FOUND/NOTFOUND) which is
reliable regardless of exitCode timing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allows switching the OpenClaw agent model (e.g. from Opus to Sonnet)
without rebuilding the container, via wrangler secret.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reduces maxConcurrent from 4 to 1 and subagents from 8 to 2 to avoid
Anthropic API rate limits. AI Gateway adds caching, rate limit buffering,
and request logging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allow ?token= query param to authenticate directly with the gateway
token, bypassing CF Access JWT requirement. This enables direct URL
access (e.g. browser bookmarks) without a CF Access self-hosted app.

Extracts timingSafeEqual to shared src/utils/timing.ts utility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add runCommandWithCleanup utility to prevent zombie process accumulation
- Add killAllGatewayProcesses to clear stuck gateway processes
- Add health check to detect default Bun server (not real gateway)
- Use rsync instead of cp for R2 restore (handles broken symlinks/.git)
- Exclude .git dirs from R2 sync
- Fix WebSocket detection (check Sec-WebSocket-Key for HTTP/2 edge)
- Queue CDP messages during browser launch to prevent dropped commands
- Fix build script to rename index.html to _admin-app.html (avoid asset collision)
- Fix asset handling config (none instead of SPA/auto-trailing-slash)
- Add Telegram webhook secret passthrough to container
- Add browser profile config for CDP in container startup
- Add openclaw doctor --fix to container startup validation
- Add debug routes: /debug/net-test, /debug/cleanup
- Change cron to every minute with process monitoring and cleanup
- Remove debug headers from HTTP proxy responses

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous container was stuck serving the default Bun server instead
of the OpenClaw gateway. Changing the stable ID forces Cloudflare to
create a fresh DO instance. All data is preserved in R2 and restored
automatically on startup.

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

Headers.get() returns null for missing headers, but the WebSocket detection
used `!== undefined` which is always truthy. This caused every HTTP request
to enter the WebSocket branch and get proxied via wsConnect, returning the
default Bun server response instead of the OpenClaw gateway UI.

Also fixes: stdout reference bugs in api.ts, gateway.mode binding issue in
start-openclaw.sh, adds FRESH_START env passthrough, adds doctor timeout,
and simplifies R2 restore with timeouts for fresh containers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ick pre-check

The /api/admin/devices endpoint called ensureMoltbotGateway() which blocked
for up to 3 minutes waiting for the gateway port. Now does a 5-second port
check and returns a gatewayStatus immediately if not ready. The frontend
auto-retries every 3 seconds and shows "Gateway is starting up..." instead
of an indefinite spinner.

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

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix DO reset loop that prevents container from starting after deploys.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The cron handler returned early after gateway restarts, skipping the R2
backup sync entirely. If the gateway was frequently restarting, backups
would never run. Also fixed the workspace sync/restore path from
/root/clawd/ to /root/.openclaw/workspace/ where OpenClaw actually
stores MEMORY.md, IDENTITY.md, and other workspace files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t-v3)

The request handler was updated to moltbot-v3 in 112ae1d but the cron
handler was not, so the cron was starting the gateway in a different
sandbox instance than requests were routed to. This caused the admin
page to spin forever since it never found a running gateway.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The check `stdout.trim() === 'FOUND'` always failed because `ls` outputs
the filename to stdout before `echo FOUND`, producing multi-line output.
Changed to `includes('FOUND') && !includes('NOTFOUND')` to correctly
detect the marker. This was the root cause of backups not running.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The workspace rsync failed silently on fresh containers because
/root/.openclaw/workspace/ didn't exist, breaking the && chain
and leaving the old .last-sync timestamp. Added mkdir -p before
rsync to ensure the directory exists.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rsync over s3fs does one HTTP request per file, making backups of even
small directories take 30+ seconds and time out. Switched to tar
archives — create compressed archive locally then copy a single file
to R2 (3 writes total instead of hundreds). Restore falls back to
legacy rsync-style directories for backward compatibility.

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

Bake workspace files into the container image as seeds. The startup
script copies them to /root/.openclaw/workspace/ only if the files
don't already exist from R2 restore, so bot-modified versions persist.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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

Comments