fix(worker): neutralize server-only at runtime so the tsx worker can boot

The worker runs worker/index.ts under tsx (plain Node) and transitively
imports lib/flags (and other server-only-guarded modules) via the generation
pipeline. `server-only` resolves to its throwing index.js outside Next's RSC
bundler, crash-looping the worker container. Copy the package's empty.js over
index.js in the final image so the runtime import is a no-op; the build-time
client/server guard already ran during `next build`. Web is unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Leon Serfaty
2026-06-20 21:31:38 -04:00
parent 328cd62766
commit 35379212fb
+6
View File
@@ -39,6 +39,12 @@ ENV HOSTNAME=0.0.0.0
ENV STORAGE_DIR=/app/storage ENV STORAGE_DIR=/app/storage
# Copy the whole built app (node_modules incl. tsx + prisma CLI, .next, source). # Copy the whole built app (node_modules incl. tsx + prisma CLI, .next, source).
COPY --from=build /app ./ COPY --from=build /app ./
# `server-only` throws at import time when resolved outside Next's RSC bundler.
# The worker runs lib/* under tsx (plain Node), which hits that throw (e.g. via
# lib/flags). Neutralize the runtime module in the FINAL image only — the
# build-time client/server guard already ran during `next build`. Web is
# unaffected: `next start` serves prebuilt output and never relies on the throw.
RUN cp node_modules/server-only/empty.js node_modules/server-only/index.js
RUN mkdir -p /app/storage/mp3 /app/storage/art /app/storage/exports RUN mkdir -p /app/storage/mp3 /app/storage/art /app/storage/exports
EXPOSE 3000 EXPOSE 3000
# Default = web; the worker service overrides this command in docker-compose.yml. # Default = web; the worker service overrides this command in docker-compose.yml.