What is the best way to use NextJS with docker? #16995
-
Hi guys, IS a good choice the image below?
Thanks so much! |
Beta Was this translation helpful? Give feedback.
Replies: 31 comments 164 replies
-
Alternatively, for yarn:
|
Beta Was this translation helpful? Give feedback.
-
This is a more optimized version leveraging multi-stage. # Install dependencies only when needed
FROM node:lts-alpine AS deps
WORKDIR /opt/app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile
# Rebuild the source code only when needed
# This is where because may be the case that you would try
# to build the app based on some `X_TAG` in my case (Git commit hash)
# but the code hasn't changed.
FROM node:lts-alpine AS builder
ENV NODE_ENV=production
WORKDIR /opt/app
COPY . .
COPY --from=deps /opt/app/node_modules ./node_modules
RUN yarn build
# Production image, copy all the files and run next
FROM node:lts-alpine AS runner
ARG X_TAG
WORKDIR /opt/app
ENV NODE_ENV=production
COPY --from=builder /opt/app/next.config.js ./
COPY --from=builder /opt/app/public ./public
COPY --from=builder /opt/app/.next ./.next
COPY --from=builder /opt/app/node_modules ./node_modules
CMD ["node_modules/.bin/next", "start"] |
Beta Was this translation helpful? Give feedback.
-
when using |
Beta Was this translation helpful? Give feedback.
-
I noticed that the SIGTERM isn't passed: CTRL-C doesn't work and I have to kill a container from a separate terminal window after the start. I tried both |
Beta Was this translation helpful? Give feedback.
This comment has been hidden.
This comment has been hidden.
-
I have docker running our NextJS v10 website with multiple environments, but since i am using |
Beta Was this translation helpful? Give feedback.
-
What would be the best way to set up a docker-compose.yml? |
Beta Was this translation helpful? Give feedback.
-
Thanks to lots of valuable feedback in this thread, we've shipped the first version of the Docker deployment docs. We will continue to evolve this with the best practices for using Next.js with containers. |
Beta Was this translation helpful? Give feedback.
-
I highly do not recommend not using Use Ref. https://github.com/GoogleContainerTools/distroless#docker |
Beta Was this translation helpful? Give feedback.
-
The official Next.js Docker image is not working for my project. It throws below excpetion on production:
It works OK on the I suggest using below much simpler
|
Beta Was this translation helpful? Give feedback.
-
@wilsonneto-dev You might wanna check this sample repo/project which integrates next.js + production ready multi-stage dockerfile + docker-compose setup https://github.com/kachar/yadi/tree/main/web/next.js The multi-stage build is explained at https://github.com/kachar/yadi#build-multi-stage-build-explained For clarity I'm posting the contents of # Build target base #
#####################
FROM node:14-alpine AS base
WORKDIR /app
ARG NODE_ENV=production
ENV PATH=/app/node_modules/.bin:$PATH \
NODE_ENV="$NODE_ENV"
RUN apk --no-cache add curl
COPY package.json yarn.lock /app/
EXPOSE 3000
# Build target dependencies #
#############################
FROM base AS dependencies
# Install prod dependencies
RUN yarn install --production && \
# Cache prod dependencies
cp -R node_modules /prod_node_modules && \
# Install dev dependencies
yarn install --production=false
# Build target development #
############################
FROM dependencies AS development
COPY . /app
CMD [ "yarn", "dev" ]
# Build target builder #
########################
FROM base AS builder
COPY --from=dependencies /app/node_modules /app/node_modules
COPY . /app
RUN yarn build && \
rm -rf node_modules
# Build target production #
###########################
FROM base AS production
COPY --from=builder /app/public /app/public
COPY --from=builder /app/.next /app/.next
COPY --from=dependencies /prod_node_modules /app/node_modules
CMD [ "yarn", "start" ]
HEALTHCHECK --interval=5s --timeout=5s --retries=3 \
CMD curl --fail http://localhost:3000 || exit 1 |
Beta Was this translation helpful? Give feedback.
-
Never start your application with https://blog.risingstack.com/graceful-shutdown-node-js-kubernetes/ |
Beta Was this translation helpful? Give feedback.
-
How are folks managing environment variables in containerized next apps, especially with SSR |
Beta Was this translation helpful? Give feedback.
-
Any graceful solutions for dealing with NextJS dynamic builds before & during docker image builds? Basically a docker container has to be up with networking so another can build via API (using getStaticProps / npm run build)? There must be a better way... If it really is for "dynamic builds" so the static pages get generated (like below), then shouldn't happen after the docker images are build instead of during?
Doesn't seem like many others encounter this for some reason. |
Beta Was this translation helpful? Give feedback.
-
This works well with # Install dependencies only when needed
FROM node:alpine AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile
# Rebuild the source code only when needed
FROM node:alpine AS builder
WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
ARG NODE_ENV=devolpement
RUN echo ${NODE_ENV}
RUN NODE_ENV=${NODE_ENV} yarn build
# Production image, copy all the files and run next
FROM node:alpine AS runner
WORKDIR /app
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# You only need to copy next.config.js if you are NOT using the default configuration
COPY --from=builder /app/next.config.js ./next.config.js
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/pages ./pages
USER nextjs
# Expose
EXPOSE 3000
# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry.
ENV NEXT_TELEMETRY_DISABLED 1
CMD ["yarn", "start"] |
Beta Was this translation helpful? Give feedback.
-
Hi,
Anyone has an experience with that? Thank you, |
Beta Was this translation helpful? Give feedback.
-
Can someone explain this? This shuts down container if website isn't up, why is that useful?
|
Beta Was this translation helpful? Give feedback.
-
We are also looking in to this and having the same problem. It would be great to hear from the devs on this? Maybe having the option to tell nextjs on startup to do the static build instead of the buildstep to pre-render static pages at runtime? Something like
Wouldn't something like this solve this issue? This probably introduce some other issues I haven't thought of but it would be interesting to hear some ideas |
Beta Was this translation helpful? Give feedback.
-
I ran into this issue and got it working with Docker while still respecting the 12 Factor App Rules, the TL;DR is you need to modify your
To access the environment variables in any page or component simply add this:
Here’s an example of what component would look like:
The real issue is the way the Dockerfile starts the app in order to load env vars we need to start it with I wrote an article with my findings if you want to get the full details of why and how it works: https://benmarte.com/blog/nextjs-in-docker/ I also made a sample repo which can be used as a template: https://github.com/benmarte/nextjs-docker I will make a PR this week to the with-docker repo. |
Beta Was this translation helpful? Give feedback.
This comment was marked as spam.
This comment was marked as spam.
-
I'm just looking into the options on this one for myself for a deployment I'm planning in the near future. It seems to me that trying to do the "next build" as part of the Dockerfile is the wrong thing to do (unless you're trying to do My original thoughts on this, before I found this thread, were simply to create a container image that was based on node, copy in package.json and the source code files and pre-install the node modules by doing This artifact is then a deployable version of the code that can be repeatably deployed/tested anywhere and all the environment variables can be managed by the release process (e.g. Helm or whatever). The obvious foreseeable drawback to this approach would be a longer delay between starting the container and container being ready to serve traffic, (i.e. while it builds the code and renders any SSG content) but I can't see that being an unmanageable amount of time. Is there anything else fundamental that I'm missing here? |
Beta Was this translation helpful? Give feedback.
-
NextJS authors: dynamic (re)building of pages can happen at run time. The initial build of the site should happen at build time. No need to rebuild the entire site at run time - just changes that are made. No need to build the entire site at run time. If you want an initial build, then that would happen at build time. Any other cases? |
Beta Was this translation helpful? Give feedback.
-
I've done some further investigation since last time I responded to this thread, so I now have a better understanding of the problem and of the pros and cons of the various solutions. Ultimately the best solution is going to be Vercel adding "runtime SSG" as a feature of Next.js - until then I've put together a blog post of my findings that others might find helpful: |
Beta Was this translation helpful? Give feedback.
-
I've been using a multi-stage build similar to many of the ones shown in this thread, but I can't manage to find a way for it to only run the run the
|
Beta Was this translation helpful? Give feedback.
-
Checkout my solution as it uses Docker best practices for security. I don't think even Vercel's solution does that fully. And it creates another user when you can use the user created by Node package itself. |
Beta Was this translation helpful? Give feedback.
-
For docker image can run multiple environments like staging, production, develop... Read here: |
Beta Was this translation helpful? Give feedback.
-
You are creating a CI/CD pipeline and want to build NextJS. However, NextJS needs another service (database, Redis, etc.) to build, and you don't want to expose your services to your host machine?Read this.
services:
pgadmin:
container_name: my-database
image: postgres
networks:
- my-net
networks:
my-net:
name: 'my-super-net'
external: true
webserver:
build:
context: .
dockerfile: Dockerfile
network: host
# Create the Docker network if not already present
docker network create my-super-net || true
# Create the Docker builder
docker buildx create --name my-builder --use --driver-opt network=my-super-net --buildkitd-flags '--allow-insecure-entitlement network.host'
# `--use` to use this builder by default
# `--driver-opt network=my-super-net` to add the Docker builder to the Docker network so it can access our services
# `--buildkitd-flags '--allow-insecure-entitlement network.host'` to allow building with --network=host
# Bootstrap the Docker builder to get it ready for use
docker buildx inspect my-builder --bootstrap
# Start the services manually
docker compose -f docker-compose.yaml up -d database
docker compose -f docker-compose.yaml up -d redis
# Build as usual
docker compose -f docker-compose.yaml build
# The build will use the `network: host`, which is not your host machine's network, but the network of your previously created builder. Your services are not exposed to your host machine. |
Beta Was this translation helpful? Give feedback.
-
Original from @dgbau (#16995 (comment))
Currently having the same issue with a similar Dockerfile. This is very annoying while trying to avoid any downtime when deploying new code changes. |
Beta Was this translation helpful? Give feedback.
-
i want to dockerize nextjs full stack project with nginx config. how can i write multistage dockerfile for my project include nginx. Please help. current nginx config: server { } Current Dockerfile : FROM node:20-alpine AS builder WORKDIR /app FROM nginx:alpine RUN addgroup --system --gid 1001 nodejs COPY --from=builder /app/public ./public RUN mkdir .next COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./standalone COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static COPY ./conf/nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 3000 |
Beta Was this translation helpful? Give feedback.
Thanks to lots of valuable feedback in this thread, we've shipped the first version of the Docker deployment docs. We will continue to evolve this with the best practices for using Next.js with containers.