2

I've NX monorepo with a NextJS web-app. It's s very simple, just one page with "hello world", with no assets and images.

I've made a Dockerfile for my webapp, below is my Dockerfile, and here are my 3 questions:

  1. it's dramatically slow on build, it takes more than 15 min to build image, also the image is more than 1.5Gb.

  2. on the NX website I found an example how to configure Nx+NextJS+vercel but didn't found example of clean Dockerfile without tying to any hosting provider, so maybe somebody could advice what's wrong with my Dockerfile

  3. not sure re last instruction: is it correct to run nextjs app with just "npm start" for production

FROM node:16-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY . .
RUN yarn install --frozen-lockfile


FROM node:16-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npx nx build webappName --prod


FROM node:16-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
COPY --from=deps /app/node_modules ./node_modules
RUN addgroup --system --gid 1001 nextgroup
RUN adduser --system --uid 1001 nextuser
COPY --from=builder /app/dist/apps/webappName ./
USER nextuser
EXPOSE 3000
ENV PORT 3000
CMD ["npm", "start"]

1
  • Q: Why is it dramatically slow on build, taking more than 15 min to build image, also the image is more than 1.5Gb? A: If you figure out why it's 1.5GB ... that will probably also explain why the build is slow! This article might help troubleshoot exactly what's happening at each stage of your build: joyfulbikeshedding.com/blog/…. See also: github.com/vercel/next.js/discussions/16995 Commented Mar 15, 2023 at 5:15

1 Answer 1

0
  1. Multi stage docker build(i.e dependency, builder & runner) can help you reduce the size of the docker image output size. As it cherry picks the files that is required to run excluding other files.
  2. NX project you need to choose if you are using distributed_cache & nx db. I have disabled as i was not using it. You can choose to do as per your need. Then you can build the nextjs project.
  3. I am using a script file that helps in configuring as per your need.

In order to deploy the project as standalone. Please pass output:'standalone' in next.config.js link

Dockerfile

FROM node:20.18.0-alpine AS base

FROM base AS deps
WORKDIR /app
RUN apk add --no-cache libc6-compat bash curl
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
RUN \
  if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
  elif [ -f package-lock.json ]; then npm ci; \
  elif [ -f pnpm-lock.yaml ]; then pnpm install --frozen-lockfile --prod; \
  else echo "No lock file found. Please add lock file. Failling the build & Exit." && exit 1; \
  fi

FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
ENV NX_DISTRIBUTED_CACHE=false \
  NX_DISABLE_DB=true \
  NEXT_TELEMETRY_DISABLED=1 \
  NODE_ENV=production

COPY . .
RUN npm run nx build website

FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production \
  NEXT_TELEMETRY_DISABLED=1
COPY apps/website/.env apps/website/.scripts/build/init.sh ./
COPY --from=builder /app/apps/website/public ./apps/website/public
COPY --from=builder /app/apps/website/.next/standalone ./
COPY --from=builder /app/apps/website/.next/static ./apps/website/.next/static
RUN chmod +x init.sh
CMD [ "sh", "init.sh" ]

init.sh


#!/bin/sh

export LC_ALL=en_US.UTF-8
cd /

cd app/
export $(grep -v '^#' .env | xargs)
export NODE_ENV=production
export DEPLOY_ENV=production
export NEXT_TELEMETRY_DISABLE=1
export HOST="0.0.0.0"
export PORT=3000

node apps/website/server.js

For more details you can refer one of my project in the github i.e my-nx-playground using nx. Especially added a dockerfile for the website project using nextjs. Hope this is exactly what you are looking for.

https://github.com/samarpanda/my-nx-playground

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.