11

When testing and using my NextJS Application with .env.local everything works great. However, when I do a production build to deploy, it can't find the .env.production values (even though its an exact copy from .env.local for now). When I added an endpoint that does a console.log(process.env) none of the .env.production values are present.

Here's my Dockerfile

# 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
RUN yarn build && yarn install --production --ignore-scripts --prefer-offline
# Production image, copy all the files and run next
FROM node:alpine AS runner
WORKDIR /app
ENV NODE_ENV production
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 ./
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
USER nextjs
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"]

and I build the image with this command:

docker build -t my-next-project .

When doing a manual build:

next build

it says in the console:

info - Loaded env from /Users/name/source/my-next-project/.env.local
info - Loaded env from /Users/name/source/my-next-project/.env.production

So it finds the two .env files...not sure what's not working here.

Edit:

Here's the log from running my docker build command docker build -t app-container .

[+] Building 140.1s (14/21) 
 => => transferring dockerfile: 37B 0.0s
 => [internal] load .dockerignore 0.0s
 => => transferring context: 2B 0.0s
 => [internal] load metadata for docker.io/library/node:alpine 1.4s
 => [auth] library/node:pull token for registry-1.docker.io 0.0s
[+] Building 140.2s (14/21) 
 => => transferring context: 290.52MB 17.2s
 => [deps 1/5] FROM docker.io/library/node:alpine@sha256:f372a9ffcec27159dc9623bad29997a1b61eafbb145dbf4f7a64568be2f59b99 0.0s
 => CACHED [deps 2/5] RUN apk add --no-cache libc6-compat 0.0s
 => CACHED [deps 3/5] WORKDIR /app 0.0s
 => [deps 4/5] COPY package.json yarn.lock ./ 0.4s
[+] Building 140.4s (14/21) 
 => [deps 1/5] FROM docker.io/library/node:alpine@sha256:f372a9ffcec27159dc9623bad29997a1b61eafbb145dbf4f7a64568be2f59b99 0.0s
[+] Building 140.5s (14/21) 
 => CACHED [deps 3/5] WORKDIR /app 0.0s
[+] Building 152.6s (22/22) FINISHED 
 => [internal] load build definition from Dockerfile 0.0s
 => => transferring dockerfile: 37B 0.0s
 => [internal] load .dockerignore 0.0s
 => => transferring context: 2B 0.0s
 => [internal] load metadata for docker.io/library/node:alpine 1.4s
 => [auth] library/node:pull token for registry-1.docker.io 0.0s
 => [internal] load build context 17.6s 
 => => transferring context: 290.52MB 17.2s 
 => [deps 1/5] FROM docker.io/library/node:alpine@sha256:f372a9ffcec27159dc9623bad29997a1b61eafbb145dbf4f7a64568be2f59b99 0.0s 
 => CACHED [deps 2/5] RUN apk add --no-cache libc6-compat 0.0s 
 => CACHED [deps 3/5] WORKDIR /app 0.0s 
 => [deps 4/5] COPY package.json yarn.lock ./ 0.4s 
 => CACHED [builder 2/6] WORKDIR /app 0.0s 
 => [builder 3/6] COPY . . 10.6s 
 => [deps 5/5] RUN yarn install --frozen-lockfile 33.0s
 => [builder 4/6] ADD ./.env.production ./.env.production 0.1s
 => [builder 5/6] COPY --from=deps /app/node_modules ./node_modules 3.0s
 => [builder 6/6] RUN NODE_ENV=production yarn build && yarn install --production --ignore-scripts --prefer-offline 89.7s
 => CACHED [runner 3/8] RUN addgroup -g 1001 -S nodejs 0.0s 
 => CACHED [runner 4/8] RUN adduser -S nextjs -u 1001 0.0s 
 => [runner 5/8] COPY --from=builder /app/public ./public 0.1s 
 => [runner 6/8] COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next 0.4s 
 => [runner 7/8] COPY --from=builder /app/node_modules ./node_modules 1.8s 
 => [runner 8/8] COPY --from=builder /app/package.json ./package.json 0.0s 
 => exporting to image 1.9s
 => => exporting layers 1.9s
 => => writing image sha256:0e529630769589eefbdb0871e7024ea7f296db978c45102e7804e489d6d2f712 0.0s
 => => naming to docker.io/library/app-container
asked Jun 7, 2021 at 2:54
9
  • try that ENV NODE_ENV = production Commented Jun 7, 2021 at 3:54
  • @Jerome that didn't make any difference. Commented Jun 7, 2021 at 3:59
  • instead of using an end-point to check, i would log into the running container and check the present env. Get the name of your running containers docker container ls, log into your container docker exec -it containerName sh check the env variables env Commented Jun 7, 2021 at 4:11
  • I get back that the NODE_ENV=production Commented Jun 7, 2021 at 4:28
  • so all is fine... Commented Jun 7, 2021 at 4:34

2 Answers 2

17
+50

If you are NOT using the default configuration you have to uncomment:

COPY --from=builder /app/next.config.js ./

in this part, you have to copy all your production files to container like your .env files from builder like:

COPY --from=builder /app/.env.production ./
answered Jun 16, 2021 at 12:53
Sign up to request clarification or add additional context in comments.

2 Comments

What is the difference in this answer from the one above "minused one"?
Better not to copy all variables into image!
1

From my experience, NextJs seems to read the .env files when it starts up. Thus, .env.production needs to be present at yarn start. But in your current Dockerfile it not copied in your runner stage. So add the following line in your runner stage:

COPY --from=builder /app/.env.production ./
answered Jun 16, 2021 at 12:39

3 Comments

The docs say environment variable inlining happens at build time. nextjs.org/docs/basic-features/environment-variables
@ckeeney yes it does. But under the section for browser environment variables only ;)
I deleted my answer which is given minus, but the solution was about only using needed variables which is safer than copying all variables in this way which might be dangerous! And the selected answer is the same with this one :S

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.