Vite dev server and Docker bind mounts: file watcher interoperability
0 reputation · 27 May 2023, 16:52 UTC
0 reputation · 27 May 2023, 16:52 UTC
Determine whether Vite’s development server can reliably detect source-file edits through Docker bind mounts without forcing polling mode, preserving fast HMR in a repeatable containerized workflow.
Vite relies on chokidar and OS-level file watchers, which can miss or delay events inside containers on macOS and Windows. Bind mounts may also introduce host-to-container permission mismatches. Enabling watcher.usePolling improves detection but increases CPU usage, so the acceptable trade-off for repeatable environments is unresolved.
Assuming current Vite releases and Docker Desktop, what conditions make bind-mounted HMR stable, and when is polling unavoidable?
35775 reputation · 28 May 2023, 03:06 UTC
Vite's default watcher (chokidar) reliably detects edits through bind mounts on Linux hosts because inotify events propagate into the container. On macOS and Windows using Docker Desktop, the virtualized filesystem layers (gRPC FUSE or 9p) typically do not forward host-side filesystem events to the container. Consequently, HMR will not trigger automatically unless you enable polling (server.watcher.usePolling: true) or move the project files entirely into the Linux filesystem (e.g., the WSL2 /home directory).
| Host OS | Event Propagation | Stable Non-Polling Setup |
|---|---|---|
| Linux | Native (inotify) | Default bind mounts work. |
| macOS | Unreliable/None | VirtioFS (experimental) or Linux VM. |
| Windows | None for /mnt/c/ |
Store project in WSL2 /home/user/. |
EACCES errors during writes, match the container user to the host user (e.g., user: "1000:1000" in docker-compose.yml). This ensures the container can modify files, though it does not fix watcher events.:cached or :delegated flags to fix HMR; these optimize read performance but do not enable event propagation.node_modules and .git via server.watcher.ignored to prevent the watcher from overloading the system.Polling is the only dependable option when using bind mounts on macOS or Windows (via /mnt/c/). The trade-offs are as follows:
To implement polling in vite.config.js:
export default defineConfig({
server: {
watcher: {
usePolling: true,
interval: 200,
useFsEvents: false
}
}
});
Verification Steps:
docker info (look for VirtioFS or WSL2).docker stats.Are your project files stored on the Windows host (/mnt/c/...) or inside the WSL2 internal filesystem (/home/...)? If they are in the internal WSL2 filesystem, you can disable polling and regain native performance.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.