개요
Cloudflare Computer는 Durable Object 내에서 SQLite 기반 가상 파일 시스템을 제공하며, 컨테이너, Shell 격리, JavaScript 격리 등 플러그 가능한 실행 백엔드를 지원합니다. 통합 진입점인 workspace.runtime.exec를 통해 코드를 실행하고, FUSE 마운트, RPC 동기화 및 영구적 상대 임포트를 지원합니다.
README 미리보기
# Cloudflare Computer\n\nCloudflare Computer is a virtual filesystem that lives inside a\nDurable Object. The Durable Object holds the authoritative state in\nSQLite and exposes one pluggable execution surface through\n`workspace.runtime`. Three backends ship today:\n\n- **Container** projects the SQLite state into a sandbox container as\n a real FUSE mount. A sandbox-side daemon (`computerd`) mounts the state\n as a filesystem and syncs changes back over a capnweb RPC channel.\n Full Linux userland, real binaries, real network.\n- **Isolate shell** runs [just-bash](https://github.com/vercel-labs/just-bash)\n in a Dynamic Worker. It reaches the authoritative Workspace over\n Workers RPC, so there is no second store or sync round trip.\n- **Isolate JavaScript** runs an ECMAScript module in a fresh Dynamic\n Worker with structured input/results, durable relative imports,\n configured libraries, Workspace-backed `node:fs/promises`, and trusted `ws:git` and\n `ws:artifacts` modules.\n\nA Workspace may register multiple backends under stable IDs.\n`workspace.runtime.exec(source, { backend })` is the single execution\nentry point; the selected backend defines whether `source` is a shell\ncommand or an ECMAScript module. Backends connect lazily on first use.\n\nWorkspace can also be constructed without a backend at all, giving\ncallers the filesystem on its own.\n\n> [!IMPORTANT]\n> **PREVIEW ONLY** This package is provided as a preview for feedback only.\n> APIs are unstable and the design is subject to change.\n>\n> Suitable for experiments, exploration and prototypes. It is NOT suitable\n> for production use at this time.\n>\n> The specification under [`docs/`](docs/) is forward-looking — read it for\n> intent, not as description of the code today.\n\n## Using it\n\nIf you want to build on Cloudflare Computer, install\n[`@cloudflare/computer`](packages/computer/README.md) and follow that\npackage's README — it has the installation steps, the entrypoint map,\nandFAQ (5)
문제 해결Cloudflare Computer에서 worker-shell exec를 실행할 때 발생하는 "Cannot read properties of undefined (reading 'WorkspaceServiceProxy')" 오류는 어떻게 해결하나요?
이 오류에는 두 가지 가능한 설정 원인이 있습니다. 둘 다 수정하세요:
1. 필수 enable_ctx_exports 호환성 플래그를 wrangler.toml에 추가하세요:
compatibility_flags = ["nodejs_compat", "experimental", "enable_ctx_exports"]
`wrangler.json`을 사용하는 경우:json{
"compatibility_flags": ["nodejs_compat", "experimental", "enable_ctx_exports"]
}
2. Worker 진입점에서 `WorkspaceServiceProxy`를 re-export하세요:jsexport { WorkspaceServiceProxy } from "@cloudflare/computer";
Wrangler를 재시작하거나 다시 배포한 후 재시도하세요:bashcurl -X POST localhost:8787/exec \
-H 'content-type: application/json' \
-d '{"cmd":"echo hi"}'
``
enable_ctx_exports가 없으면 ctx.exports가 undefined가 되고, re-export가 없으면 WorkspaceServiceProxy 자체가 누락됩니다. 두 가지 실수 모두 동일한 오해를 유발하는 오류를 발생시킵니다. 이 문제는 @cloudflare/computer@0.2.0, wrangler@4.123.0, workerd@1.20260811.1`에서 관찰되었습니다.문제 해결`oldText`가 정확히 일치하지 않을 때 @cloudflare/computer `edit` 도구가 파일 전체를 다시 작성하고 스마트 따옴표, 대시 또는 후행 공백을 제거하는 문제를 해결하는 방법은 무엇인가요?
근본 원인: 정확한 매칭에 실패하면 packages/computer/src/tools/fs/edit-diff.ts의 applyEditsToNormalizedContent가 퍼지 정규화된 복사본을 대상으로 매칭을 수행하지만, 쓰기와 diff 양쪽 모두에 그 정규화된 복사본을 baseContent로 잘못 사용합니다. 따라서 관련 없는 유니코드 구두점과 후행 공백이 평탄화됩니다.
즉각적인 해결 방법: oldText를 바이트 단위로 정확하게 만드십시오. 실수로 포함된 후행 공백을 제거하고 스마트 따옴표(U+201C/U+201D), 엠 대시(U+2014) 및 파일의 유니코드 정규화를 유지하십시오. 재현을 위해서는 다음을:
oldText: "let target = 1; "
다음과 같이 변경하십시오:
oldText: "let target = 1;"
보이지 않는 문자는 sed -n l path/to/file 또는 od -c path/to/file로 확인하십시오.
영구 수정: 정규화된 콘텐츠는 매칭에만 사용하고, 정규화된 문자에서 원본 파일로 돌아가는 소스 오프셋 맵을 유지하며, 치환을 원본 콘텐츠에 삽입하고, 원본 대 편집된 콘텐츠로부터 diff를 생성하십시오. 유니코드 정규화로 인해 문자가 병합되거나 매칭이 확장된 합자의 일부만 포함하는 경우와 같은 모호한 매핑은 거부하십시오. 이는 PR fix: preserve files during fuzzy edits (#51)에서 구현되었습니다.
영향 받는 버전: 커밋 76d9e75의 @cloudflare/computer 0.1.0-alpha.1. 다음으로 검증하십시오:
npm test --workspace @cloudflare/computer -- src/tools/fs/repro.test.ts문제 해결Worker JavaScript capability 크기 오류에 구성된 바이트 제한 대신 리터럴 ${maxCapabilityBytes}가 표시되는 이유는 무엇입니까?
제한 값은 크기 비교에서 보간되지만, 오류 메시지는 일반 큰따옴표 문자열로 생성되므로 ${maxCapabilityBytes}가 치환되지 않습니다. 모듈을 생성할 때 구성된 값을 삽입하여 packages/computer/src/backends/worker-javascript/module-graph.ts의 capabilitiesModule()를 수정하세요. 예: throw new Error(${JSON.stringify(Workspace capability request exceeds ${maxCapabilityBytes} bytes.)});. maxCapabilityBytes: 256인 경우 생성된 런타임 코드는 다음과 같아야 합니다: throw new Error("Workspace capability request exceeds 256 bytes.");. Worker 모듈을 다시 빌드하거나 재생성한 후 재배포하세요. 가능한 경우 수동으로 패치하는 대신 PR #99가 포함된 릴리스로 업데이트하세요.
문제 해결computerd 0.3.0에서 Cap'n Web WebSocket 엔드포인트가 /ws에서 /api로 이동한 이유는 무엇인가요?
computerd 0.3.0에서 Cap'n Web 엔드포인트가 통합되었습니다: WebSocket 연결에는 /ws 대신 /api를 사용하세요. 서버는 Upgrade 헤더가 포함된 GET 요청을 통해 WebSocket 요청과 HTTP 요청을 구분합니다. 기존 /ws 경로는 제거되었습니다. 또한 0.3.0에서 HTTP 배치 지원도 제거되었는데, 이는 streams 마이그레이션 이후 RPC 호출에서 반환된 스트림에 연결할 수 없었기 때문입니다.
문제 해결문서에는 심볼릭 링크가 내부용이라고 되어 있는데, 왜 Workspace.fs는 symlink(), readlink(), lstat(), chmod()를 노출하나요?
문서가 오래되었습니다. 배포된 API에서 이러한 메서드들은 의도적으로 WorkspaceFilesystem에 공개되어 있으며, WorkspaceFilesystemStub에 의해 Workers RPC 경계를 넘어 미러링됩니다.
이들을 Promise 기반 파일시스템 API로 사용하세요:
await workspace.fs.symlink(targetPath, linkPath);
const target = await workspace.fs.readlink(linkPath);
const linkStats = await workspace.fs.lstat(linkPath);
await workspace.fs.chmod(filePath, 0o644);
stat()은 후행 심볼릭 링크를 따라가 대상을 보고하는 반면, lstat()은 링크 자체를 보고합니다. 관련 오류로는 경로가 존재하지 않을 때의 ENOENT, 잘못된 인수나 작업에 대한 EINVAL, 심볼릭 링크가 너무 많이 발견될 때의 ELOOP가 있습니다.
해결 방법은 docs/04_filesystem_interface.md를 업데이트하여 symlink, readlink, lstat, chmod를 문서화하고, 심볼릭 링크가 내부 전용이라는 주장을 제거하는 것입니다. 이러한 메서드들을 제거하는 것은 호환성을 깨는 API 변경이 될 것입니다.