fix(docker): give the development image the web source it compiles from
`docker compose -f docker-compose.dev.yml up` came up with a dead frontend: the development stage's supervisor program runs `node scripts/dev.mjs`, and that path does not exist in the image. The stage builds `FROM production`, whose ./web is `.next/standalone/`, then cherry-picked three files on top. Verified against a real standalone build — its root holds exactly `server.js`, `package.json`, a traced `node_modules` and the dist dir. Every source file and every config is absent, so `scripts/` was only the first thing to fail; `tsconfig.json`, `tailwind.config.js`, `postcss.config.js`, `features/`, `types/` and `proxy.ts` were missing too, and the compose mount list covers none of them either. So take the builder's web tree wholesale instead of naming files that keep drifting as web/ grows top-level entries. `--chown` during the copy keeps node_modules from being re-layered, and the inherited production build is cleared so `next dev` starts from an empty cache rather than a half-valid one. #906 also reported this as two `[program:frontend]` blocks in one supervisor config, with the fix being to delete the dev.mjs one. That reading is wrong: the blocks are in different build stages (`FROM production AS development`), the production image has exactly one and is unaffected, and deleting the dev block would have made the development image serve a production build with no hot reload. The production stage is untouched here. Not build-verified — no Docker daemon available on this machine.
This commit is contained in:
+14
-6
@@ -443,16 +443,24 @@ ENTRYPOINT ["/app/entrypoint.sh"]
|
|||||||
# ============================================
|
# ============================================
|
||||||
FROM production AS development
|
FROM production AS development
|
||||||
|
|
||||||
# Re-add full node_modules for development hot-reload
|
# `next dev` compiles from source, so the development image needs the whole
|
||||||
# (Production uses standalone output which doesn't include full node_modules)
|
# web tree. This used to cherry-pick node_modules, package.json and
|
||||||
COPY --from=frontend-builder /app/web/node_modules ./web/node_modules
|
# next.config.js on top of the production stage — but that stage's ./web is
|
||||||
COPY --from=frontend-builder /app/web/package.json ./web/package.json
|
# `.next/standalone/`, a compiled server bundle carrying no sources, no
|
||||||
COPY --from=frontend-builder /app/web/next.config.js ./web/next.config.js
|
# tsconfig and no scripts/. So the supervisor program below launched
|
||||||
|
# `node scripts/dev.mjs` against a path that never existed, the dev frontend
|
||||||
|
# went FATAL, and the image looked broken (#906). Taking the builder's tree
|
||||||
|
# wholesale also stops the list from drifting each time web/ grows a
|
||||||
|
# top-level entry. `--chown` during the copy avoids re-layering node_modules.
|
||||||
|
COPY --chown=deeptutor:deeptutor --from=frontend-builder /app/web ./web
|
||||||
|
|
||||||
# `next dev` runs as the unprivileged deeptutor user (via `user=deeptutor` in
|
# `next dev` runs as the unprivileged deeptutor user (via `user=deeptutor` in
|
||||||
# the supervisord config) and must create/write its build cache under
|
# the supervisord config) and must create/write its build cache under
|
||||||
# /app/web/.next, so give that user ownership of the web dir and the cache.
|
# /app/web/.next, so give that user ownership of the web dir and the cache.
|
||||||
RUN mkdir -p /app/web/.next \
|
# The production build copied in above is not reusable by `next dev`, so it
|
||||||
|
# starts from an empty cache rather than a half-valid one.
|
||||||
|
RUN rm -rf /app/web/.next \
|
||||||
|
&& mkdir -p /app/web/.next \
|
||||||
&& chown deeptutor:deeptutor /app/web /app/web/.next
|
&& chown deeptutor:deeptutor /app/web /app/web/.next
|
||||||
|
|
||||||
# Install development tools
|
# Install development tools
|
||||||
|
|||||||
@@ -24,9 +24,12 @@ services:
|
|||||||
- ./deeptutor_cli:/app/deeptutor_cli:ro
|
- ./deeptutor_cli:/app/deeptutor_cli:ro
|
||||||
- ./scripts:/app/scripts:ro
|
- ./scripts:/app/scripts:ro
|
||||||
|
|
||||||
# Mount frontend source for hot-reload
|
# Mount frontend source for hot-reload. Anything not listed here still
|
||||||
|
# ships inside the image (see the development stage in Dockerfile) — it
|
||||||
|
# just will not hot-reload.
|
||||||
- ./web/app:/app/web/app:ro
|
- ./web/app:/app/web/app:ro
|
||||||
- ./web/components:/app/web/components:ro
|
- ./web/components:/app/web/components:ro
|
||||||
|
- ./web/features:/app/web/features:ro
|
||||||
- ./web/lib:/app/web/lib:ro
|
- ./web/lib:/app/web/lib:ro
|
||||||
- ./web/hooks:/app/web/hooks:ro
|
- ./web/hooks:/app/web/hooks:ro
|
||||||
- ./web/context:/app/web/context:ro
|
- ./web/context:/app/web/context:ro
|
||||||
|
|||||||
Reference in New Issue
Block a user