feat(dev): docker compose watch — live-reload for api and web - #9
Merged
Conversation
Adds a first-class watch mode to the dev stack. `docker compose watch` starts the stack and live-reloads on edits: - `sync` api/web/shared source into the running container, where the in-container watcher reloads (vite HMR for web, `tsx watch` restart for api). Sync writes into the container's own filesystem rather than through a bind mount, so it also works on macOS/Windows, where bind-mount inotify events don't propagate — the reason a plain bind-mount setup "doesn't reload" there. - `rebuild` the image when a service's package.json or the lockfile changes (adding a dependency no longer needs a manual --build). - `sync+restart` web on a vite.config.ts / tsr.config.json change (vite reads them only at startup). The router's generated tree + temp dir (gitignored) are excluded from the sync so the container owns its own codegen. The src bind mounts are removed (sync replaces them). Plain `docker compose up` still runs the stack as built (no watching) — what the CI smoke job uses; verified it still serves and generates routeTree.gen.ts in-container without the mount. README updated. Verified: `docker compose watch` reloads web (~1s) and api (tsx restart) on edits. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Owner
Author
|
LGTM. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a first-class
docker compose watchdev loop that live-reloads both services on edits.Why
The stack bind-mounted
srcand relied on the in-container watchers (vite HMR /tsx watch) seeing changes through the mount. That works on native Linux but not on macOS/Windows, where bind-mount inotify events don't propagate — so "watch doesn't reload." It also can't react to dependency changes (adding a dep needs a manual--build).What
develop.watchon both services:syncapi/web/shared source into the running container. Sync writes into the container's own filesystem (via the Docker API), not through a bind mount, so the in-container watcher fires on every platform.rebuildthe image when that service'spackage.jsonorpnpm-lock.yamlchanges.sync+restartweb on avite.config.ts/tsr.config.jsonchange (vite reads them only at startup). The router's generated tree + temp dir (gitignored) are excluded from the sync so the container owns its codegen.The
srcbind mounts are removed (sync replaces them, and keeping them would defeat the cross-platform fix). Plaindocker compose upstill runs the stack as built (no watching) — what the CI smoke job uses.Verified locally
docker compose watch: editing a web file reloads via HMR (~1s); editing an api file triggers[tsx] change … Restarting…(~1s). Log showsSyncing service "web"/"api".docker compose up(smoke-job path) still passes without the bind mount: API health OK, web shell has#root, androuteTree.gen.tsis generated in the container (vite's router plugin runs on startup regardless of the mount).docker compose configvalidates; lint/fmt green.README's "Getting started" updated to lead with
docker compose watch.🤖 Generated with Claude Code