Skip to content

fix: resolve Docker performance issues on Windows#17

Open
bashar-qassis wants to merge 5 commits into
mainfrom
fix/docker-windows-perf
Open

fix: resolve Docker performance issues on Windows#17
bashar-qassis wants to merge 5 commits into
mainfrom
fix/docker-windows-perf

Conversation

@bashar-qassis
Copy link
Copy Markdown
Owner

Summary

  • Replace bind-mount with develop.watch — the - .:/app bind-mount crossed the WSL2↔Windows filesystem bridge on every source file read. Source is baked into the image via COPY . .; changes synced via Docker's internal protocol.
  • Tune BEAM schedulerERL_FLAGS: "+sbwt none +sbwtdcpu none +sbwtdio none" disables scheduler busy-waiting that starved threads in WSL2, reducing per-request latency.
  • Disable expensive LiveView checks in DockerPHX_EXPENSIVE_CHECKS=false turns off assign/slot validation on every render (native dev keeps them on).
  • Fix CSS — excluded priv/static/assets/ from sync so Tailwind/esbuild output isn't overwritten by stale host files. Added mix assets.build before server start.
  • Add mix assets.vendor to startup — installs heroicons SVGs previously from host bind-mount.
  • Fix pre-commit hook — added #!/bin/sh shebang (root cause of Exec format error) and .husky/* text eol=lf in .gitattributes.

New workflow

```bash
docker compose -f docker-compose.dev.yml build --no-cache
docker compose -f docker-compose.dev.yml watch
```

Test plan

  • Build completes without errors
  • Server at localhost:4000 with correct CSS
  • Editing .ex files triggers recompile and LiveView updates
  • Page loads noticeably faster
  • Pre-commit hook runs without Exec format error

…Windows

The - .:/app bind-mount crosses the WSL2<->Windows filesystem boundary on every
source file read (the Elixir compiler reads all .ex files on recompile), causing
significant latency. Replace it with Docker Compose develop.watch, which syncs
changed files via Docker's internal protocol, bypassing the slow bridge entirely.

- Dockerfile.dev: add COPY . . to bake initial source into the image layer
- docker-compose.dev.yml: remove .:/app bind-mount, add develop.watch for lib/
  config/ priv/ test/ assets/ with rebuild triggers on mix.exs/mix.lock
- .dockerignore: add .worktrees/ exclusion; clarify test/ is synced at runtime

New workflow: `docker compose -f docker-compose.dev.yml watch`
Two root causes of sluggish page loads in Docker on Windows:

1. BEAM busy-wait: idle schedulers spin on vCPUs by default, starving each
   other in WSL2's shared VM. ERL_FLAGS +sbwt none disables spinning so
   schedulers sleep immediately when idle, reducing per-request latency.

2. enable_expensive_runtime_checks: LiveView validates assigns, slots, and
   other invariants on every render. In a constrained container environment
   this is noticeably slow. PHX_EXPENSIVE_CHECKS=false disables it in Docker
   while native dev keeps it on (env var defaults to "true").
…before server

develop.watch was syncing priv/ from the Windows host into the container,
overwriting freshly-compiled Tailwind/esbuild output with stale host files.
Exclude priv/static/assets/ from the sync so the container's own build is
authoritative.

Add mix assets.build to the startup sequence so CSS/JS are ready before the
first request rather than racing the watcher's initial build.

Fix .gitattributes to enforce LF for .husky/* so git on Windows no longer
checks out the pre-commit hook with CRLF, which causes Exec format error in
bash. This unblocks all future commits without --no-verify.
heroicons SVGs are installed to assets/vendor/ by a mix task from the heroicons
dependency. With the bind-mount those files came from the Windows host; with
COPY . . they must be generated at container startup.

Also add #!/bin/sh shebang to pre-commit hook — the real fix for Exec format
error on Windows. Without a shebang git tries to exec the file as a binary
and fails; with one, sh is invoked which handles the script correctly.
eol=lf in .gitattributes does not override core.autocrlf=true on checkout.
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