Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docker/Dockerfile.prod
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,20 @@ RUN cd /app/apps/web \
&& pnpm --filter @inboxzero/worker deploy --legacy --prod /tmp/apps/worker \
&& rm -rf apps/web/.next/cache

# Tracing resolves meriyah through the `require` condition and ships only
# dist/meriyah.cjs, but @sentry/nextjs imports it as ESM at runtime. Kept narrow
# on purpose; tracing omits files by design. outputFileTracingIncludes does not
# work here, Turbopack builds skip collect-build-traces.
RUN set -eux; \
src=/app/node_modules/meriyah/dist; \
test -f "$src/meriyah.mjs"; \
found=0; \
for d in $(find /app/apps/web/.next/standalone -type d -path '*/node_modules/meriyah/dist'); do \
cp "$src/meriyah.mjs" "$src/meriyah.min.mjs" "$d/"; \
found=$((found + 1)); \
done; \
test "$found" -gt 0

RUN rm -f /app/apps/web/.env /app/apps/web/.next/standalone/apps/web/.env

FROM node:24-alpine AS runner
Expand All @@ -126,6 +140,10 @@ RUN test -f apps/web/server.js \
COPY docker/scripts /app/docker/scripts
RUN chmod +x /app/docker/scripts/*.sh

# The check above only proves `next` resolves. Boot the server too, so a broken
# traced output fails here instead of 500ing every request at runtime.
RUN /app/docker/scripts/smoke-standalone.sh

# Install Prisma CLI globally for migrations
RUN npm install -g prisma@7.3.0
# Set NODE_PATH so prisma/config imports resolve correctly
Expand Down
33 changes: 33 additions & 0 deletions docker/scripts/smoke-standalone.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/sh
# Boot the standalone server and fail if it cannot load its instrumentation
# hook. Resolving the package by name is not enough: `pnpm deploy` leaves a
# complete copy in apps/web/node_modules that resolves fine even when the
# traced copy the server actually uses is incomplete.
set -e

LOG=/tmp/smoke-standalone.log

node /app/apps/web/server.js >"$LOG" 2>&1 &
PID=$!
trap 'kill "$PID" 2>/dev/null || true' EXIT

waited=0
until grep -q "Ready in" "$LOG" 2>/dev/null; do
kill -0 "$PID" 2>/dev/null || { echo "server exited before becoming ready"; tail -20 "$LOG"; exit 1; }
waited=$((waited + 1))
[ "$waited" -lt 60 ] || { echo "server never became ready"; tail -20 "$LOG"; exit 1; }
sleep 1
done

# The hook is evaluated on the request path, so make one request before judging.
# Its status does not matter; there is no database here and a 500 is expected.
wget -q -O /dev/null -T 5 http://127.0.0.1:3000/login 2>/dev/null || true
sleep 2

if grep -q "Failed to load external module" "$LOG"; then
echo "Standalone server cannot load its instrumentation hook:"
grep -m1 "Failed to load external module" "$LOG"
exit 1
fi

echo "Standalone smoke test passed."