How to Debug FUSE Mount Issues in Computerd Using the Real-FUSE Approach
Enable real-FUSE debugging in computerd by setting FUSE_MOUNT=fuse, running the daemon inside a privileged Docker container with the host's /dev/fuse device mounted, and verifying the backend via the /__computerd/info HTTP endpoint.
computerd is the Cloudflare Computer daemon that exposes a DO-side virtual file system (VFS) to containers through a FUSE mount. While the daemon defaults to auto-detecting the best FUSE backend, subtle bugs—permission errors, stale attributes, and write-buffer flush failures—only manifest with the kernel FUSE driver. This guide covers the complete real-FUSE debugging workflow as implemented in cloudflare/computer.
Why Real-FUSE Debugging Matters
By default, computerd probes for FUSE availability and falls back to a userspace shim when /dev/fuse is unavailable. The shim masks kernel-specific behavior, so production issues like EPERM on mount, attribute caching bugs, or delayed write propagation require testing against the actual kernel driver.
The real-FUSE approach forces computerd to use the native driver and exposes full kernel logging for diagnosis.
Step 1: Force the Kernel FUSE Driver
Set FUSE_MOUNT to bypass auto-detection and require the real backend:
| Platform | Environment Variable |
|---|---|
| Linux | FUSE_MOUNT=fuse |
| macOS | FUSE_MOUNT=macfuse |
This configuration is documented in [packages/computerd/README.md](packages/computerd/README.md), which describes the FUSE_MOUNT values and their fallback behavior.
Step 2: Configure a Privileged Container
The daemon needs elevated capabilities to perform kernel FUSE mounts. The test harness in [packages/computerd/src/exec/runner.fuse.test.ts](packages/computerd/src/exec/runner.fuse.test.ts) demonstrates the required Docker flags:
docker run --rm -it \
--privileged \
-v /dev/fuse:/dev/fuse \
-e FUSE_MOUNT=fuse \
-e MOUNT_POINT=/workspace \
-e PORT=45678 \
cloudflare/computerd:latest \
sh -c "npm exec --workspace @cloudflare/computerd -- bin/computerd"
Critical flags explained:
--privileged— GrantsCAP_SYS_ADMINand other capabilities required formount(2)syscalls-v /dev/fuse:/dev/fuse— Exposes the host's FUSE device node to the containerFUSE_MOUNT=fuse— Forces kernel driver selection instead of the shim fallback
Step 3: Verify Real-FUSE Activation
Once running, confirm the backend via the injected service endpoint documented in [docs/07_injected_service.md](docs/07_injected_service.md):
curl http://localhost:45678/__computerd/info | jq .
The response should contain "fuse" in the backend field. If it shows "shim" or "nodefs", the kernel driver failed to initialize—check that /dev/fuse exists inside the container and that --privileged was applied.
Step 4: Exercise the FUSE Mount
Trigger filesystem operations through computerd's RPC APIs to stress-test the mount. The real-FUSE test case in [packages/computerd/src/cli/computerd.test.ts](packages/computerd/src/cli/computerd.test.ts) validates this flow:
# Write through the exec API
curl -X POST http://localhost:45678/exec \
-H "Content-Type: application/json" \
-d '{"cmd":["/bin/bash","-c","echo hello > /workspace/hello.txt"]}'
# Read back via the mount directly
cat /workspace/hello.txt
Operations that create, modify, or stat files will generate FUSE requests visible in kernel logs.
Step 5: Capture Kernel-Level Diagnostics
Enable verbose FUSE tracing to observe the request-response cycle:
# Add debug logging to the container launch
-e FUSE_DEBUG=1
Logs appear on stderr and can be retrieved with docker logs. For deeper analysis, inspect kernel messages inside the privileged container:
dmesg | grep -i fuse
The skill file at [.agents/skills/debugging-computerd-fuse/SKILL.md](.agents/skills/debugging-computerd-fuse/SKILL.md) provides structured guidance on log collection and interpretation.
Step 6: Diagnose Common Failure Modes
| Symptom | Root Cause | Fix |
|---|---|---|
Falls back to shim (backend: "nodefs") |
/dev/fuse missing in container |
Verify -v /dev/fuse:/dev/fuse and host driver installation |
EPERM on mount syscall |
Missing CAP_SYS_ADMIN |
Add --privileged or explicit --cap-add SYS_ADMIN |
| Stale file attributes | Kernel attribute caching | Set COMPUTERD_FUSE_AUTO_CACHE=0 to disable caching |
| Write buffering delays | FUSE writeback cache | Force synchronous writes or reduce buffer sizes |
The guard in [packages/computerd/README.md](packages/computerd/README.md) automatically skips real-FUSE tests when /dev/fuse is absent, preventing false failures.
Step 7: Iterate and Validate Changes
After modifying environment variables or source code:
- Rebuild the workspace:
npm run build - Restart the privileged container with updated flags
- Verify RPC contract compliance per [
docs/08_capnweb_interface.md](docs/08_capnweb_interface.md) - Re-run the test suite to confirm FUSE behavior stability
Summary
- Force kernel FUSE with
FUSE_MOUNT=fuse(Linux) ormacfuse(macOS) - Run privileged with
--privilegedand host/dev/fusemounted - Verify activation via
GET /__computerd/infoendpoint - Enable tracing with
FUSE_DEBUG=1and inspectdmesgfor kernel errors - Address common issues: missing device node, capability errors, and attribute caching
- Maintain RPC stability when iterating on FUSE-related changes
Frequently Asked Questions
What does FUSE_MOUNT=auto do and why avoid it for debugging?
The auto setting probes /dev/fuse and macFUSE availability, then falls back to the userspace shim if neither is accessible. For debugging production FUSE issues, auto masks the very behavior you need to reproduce. Always set FUSE_MOUNT=fuse or macfuse explicitly to guarantee kernel driver usage.
Why is --privileged required instead of just --cap-add SYS_ADMIN?
While --cap-add SYS_ADMIN grants the mount capability, the kernel FUSE driver also requires access to the device node permissions and may need additional capabilities for security module interactions. The test harness in runner.fuse.test.ts uses --privileged as the reliable baseline;最小化特权化可作为后续优化探索。
How do I confirm writes actually propagated through FUSE rather than cached locally?
Write through the computerd HTTP API (/exec or /pull), then read the same path directly from the mount point with standard filesystem tools like cat or stat. If the content differs, the VFS write buffer has not flushed—check COMPUTERD_FUSE_AUTO_CACHE settings and FUSE debug logs for flush operations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →