From ffdedc9841dcb202eb3dd6641c9a24370c8a3c62 Mon Sep 17 00:00:00 2001 From: Ho Ngoc Hai Date: Tue, 14 Apr 2026 12:49:08 +0700 Subject: [PATCH] =?UTF-8?q?fix:=20API+Web=20Dockerfiles=20=E2=80=94=20mock?= =?UTF-8?q?=20husky,=20fresh=20prod=20deps=20install?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit API: Remove --ignore-scripts, mock husky binary instead so postinstall scripts (like prisma) run correctly while avoiding git hook errors. Web: Remove broken flatten stage entirely. Install fresh prod deps in production stage (same approach as API) to avoid pnpm symlink issues. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/api/Dockerfile | 4 +++- apps/web/Dockerfile | 42 +++++++++++------------------------------- 2 files changed, 14 insertions(+), 32 deletions(-) diff --git a/apps/api/Dockerfile b/apps/api/Dockerfile index b51e3dc..0fc6644 100644 --- a/apps/api/Dockerfile +++ b/apps/api/Dockerfile @@ -55,8 +55,10 @@ ENV NODE_ENV=production COPY --from=deps /app/pnpm-lock.yaml /app/pnpm-workspace.yaml /app/package.json /app/turbo.json /app/ COPY --from=deps /app/apps/api/package.json /app/apps/api/ COPY --from=deps /app/prisma /app/prisma +# Mock husky (git hooks tool) so postinstall scripts run without git RUN corepack enable && corepack prepare pnpm@10.27.0 --activate \ - && cd /app && pnpm install --frozen-lockfile --filter @goodgo/api... --prod --ignore-scripts \ + && printf '#!/bin/sh\nexit 0' > /usr/local/bin/husky && chmod +x /usr/local/bin/husky \ + && cd /app && pnpm install --frozen-lockfile --filter @goodgo/api... --prod \ && npx prisma generate # Copy compiled application COPY --from=build --chown=node:node /app/apps/api/dist ./dist diff --git a/apps/web/Dockerfile b/apps/web/Dockerfile index 886aba6..1a922be 100644 --- a/apps/web/Dockerfile +++ b/apps/web/Dockerfile @@ -17,34 +17,6 @@ COPY tsconfig.base.json ./ COPY apps/web/ apps/web/ RUN cd apps/web && npx next build -# ---- Flatten standalone ---- -# Next.js standalone with pnpm creates symlinks that point outside the standalone dir. -# We copy .pnpm (real files), then fix symlinks to point to local .pnpm store. -FROM node:22-slim AS flatten -WORKDIR /app -COPY --from=build /app/apps/web/.next/standalone/ /standalone/ - -# Copy .pnpm store (real files) and rebuild top-level symlinks -RUN cp -r /standalone/node_modules/.pnpm /app/node_modules/.pnpm 2>/dev/null || true && \ - # For each broken symlink in standalone/node_modules, find the package in .pnpm and link it - for link in /standalone/node_modules/*; do \ - name=$(basename "$link"); \ - [ "$name" = ".pnpm" ] && continue; \ - if [ -L "$link" ]; then \ - # Find the real package dir in .pnpm - real=$(find /app/node_modules/.pnpm -path "*/$name/package.json" -not -path "*/node_modules/.pnpm/*" 2>/dev/null | head -1); \ - if [ -n "$real" ]; then \ - ln -sf "$(dirname "$real")" "/app/node_modules/$name"; \ - fi; \ - elif [ -d "$link" ]; then \ - cp -r "$link" "/app/node_modules/$name"; \ - fi; \ - done && \ - # Copy server files from apps/web - cp -r /standalone/apps/web/* /app/ 2>/dev/null || true && \ - cp -r /standalone/apps/web/.next /app/.next 2>/dev/null || true && \ - rm -rf /standalone - # ---- Production ---- FROM node:22-slim AS production RUN apt-get update && apt-get install -y --no-install-recommends dumb-init && rm -rf /var/lib/apt/lists/* @@ -55,9 +27,17 @@ ENV NEXT_TELEMETRY_DISABLED=1 ENV HOSTNAME=0.0.0.0 ENV PORT=3000 -# Copy flattened standalone -RUN mkdir -p ./public -COPY --from=flatten --chown=node:node /app ./ +# Install production deps fresh (pnpm standalone output has broken symlinks) +COPY --from=deps /app/pnpm-lock.yaml /app/pnpm-workspace.yaml /app/package.json /app/turbo.json ./ +COPY --from=deps /app/apps/web/package.json ./apps/web/ +RUN corepack enable && corepack prepare pnpm@10.27.0 --activate \ + && printf '#!/bin/sh\nexit 0' > /usr/local/bin/husky && chmod +x /usr/local/bin/husky \ + && pnpm install --frozen-lockfile --filter @goodgo/web... --prod + +# Copy standalone server.js (the entrypoint Next.js generates) +COPY --from=build --chown=node:node /app/apps/web/.next/standalone/apps/web/server.js ./server.js +# Copy .next build output +COPY --from=build --chown=node:node /app/apps/web/.next/standalone/apps/web/.next ./.next COPY --from=build --chown=node:node /app/apps/web/.next/static ./.next/static # Copy public assets if any exist (may be empty) COPY --from=build --chown=node:node /app/apps/web/public ./public