Next.js Discord

Discord Forum

Env variable & Docker build fail

Answered
iyxan23 posted this in #help-forum
Open in Discord
Avatar
I have a dockerized NextJS app, and I recently added Minio's SDK to it, only to find out that it doesn't build properly because NextJS evaluates the global S3 instance (even though it probably doesn't need to), resulting the build to fail because the environment variables are not set on build time.

This error happened during NextJS' "Collecting page data" phase:
38.58 InvalidEndpointError: Invalid endPoint : undefined
38.58     at new TypedClient (/app/.next/server/chunks/7510.js:14:84432)
38.58     at new Client (/app/.next/server/chunks/7510.js:18:44349)
38.58     at 48750 (/app/.next/server/chunks/8750.js:1:22219)
38.58     at __webpack_require__ (/app/.next/server/webpack-runtime.js:1:161)
38.58     at 76307 (/app/.next/server/app/api/trpc/i/[instance_id]/[trpc]/route.js:1:1033)
38.58     at __webpack_require__ (/app/.next/server/webpack-runtime.js:1:161)
38.58     at __webpack_exec__ (/app/.next/server/app/api/trpc/i/[instance_id]/[trpc]/route.js:1:2013)
38.58     at /app/.next/server/app/api/trpc/i/[instance_id]/[trpc]/route.js:1:2075
38.58     at __webpack_require__.X (/app/.next/server/webpack-runtime.js:1:1735)
38.58     at /app/.next/server/app/api/trpc/i/[instance_id]/[trpc]/route.js:1:2026
38.58 
38.59 > Build error occurred
38.59 Error: Failed to collect page data for /api/trpc/i/[instance_id]/[trpc]
38.59     at /app/node_modules/next/dist/build/utils.js:1211:15
38.59     at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
38.59   type: 'Error'
38.59 }
Answered by iyxan23
okay somehow I fixed it by making the s3 imports to be dynamic:
const { s3 } = await import("@/s3/client");
// use s3

I'm guessing it's because NextJS evaluates every export variables that is statically imported using the import syntax?
View full answer

6 Replies

Avatar
I'm currently using tRPC v10 and some of the routers imports the following s3 file:
import * as Minio from "minio";
import { env } from "@/env"; // <- uses t3-oss's env

export const s3 = new Minio.Client({
  endPoint: env.S3_ENDPOINT,
  port: env.S3_PORT,
  useSSL: env.S3_USE_SSL,
  accessKey: env.S3_ACCESS_KEY,
  secretKey: env.S3_SECRET_KEY,
});
export const BUCKET_NAME = env.S3_BUCKET_NAME;


I have no idea how to make NextJS not evaluate the s3 file, also I don't see why NextJS would need to collect "page data" of the tRPC API; at least that's what I think NextJS is doing here. Would really appreciate some help!
here's my dockerfile if its somehow needed
##### DEPENDENCIES
# does an npm ci

FROM node:20-slim AS deps

RUN apt-get update -y && apt-get install -y openssl

WORKDIR /app
COPY package.json package-lock.json .

RUN npm ci
RUN npx prisma version

##### MINIMAL
# is a target for docker compose watch

FROM node:20-slim AS minimal

RUN addgroup --system --gid 1001 app
RUN adduser --system --uid 1001 app

USER app
WORKDIR /app

COPY --from=deps /app/node_modules ./node_modules
COPY --chown=app:app . .

##### BUILDER
# builds the app by `npm run build`

FROM node:20-slim AS builder

RUN apt-get update -y && apt-get install -y openssl

RUN addgroup --system --gid 1001 app
RUN adduser --system --uid 1001 app

USER app
WORKDIR /app

COPY --from=minimal --chown=app:app /app .

RUN npx prisma generate
RUN SKIP_ENV_VALIDATION=1 npm run build

##### RUNNER
# does a production run by `node server.js` with the compiled stuff

FROM node:20-slim AS runner

RUN apt-get update -y && apt-get install -y openssl

WORKDIR /app

ENV NODE_ENV production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/next.config.js ./

COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs
EXPOSE 3000
ENV PORT 3000

CMD ["node", "server.js"]
Avatar
okay somehow I fixed it by making the s3 imports to be dynamic:
const { s3 } = await import("@/s3/client");
// use s3

I'm guessing it's because NextJS evaluates every export variables that is statically imported using the import syntax?
Answer
Avatar
still not perfectly sure why this works, would really love if someone could shed some light
Avatar
relevant discussion if anyone is interested https://github.com/vercel/next.js/discussions/35534