R
Railway4mo ago
Sam

Dockerized next.js app - not getting environment variables on runtime

Hi there, I'm having troubles dockerizing my next.js app, at this point I'm able to get it building and using ARG to get the environment variables on buildtime but for some reason they're not being passed through on runtime. Here's my dockerfile:
FROM node:18-alpine AS base

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

ENV BOT_WEBHOOK_API_KEY=$BOT_WEBHOOK_API_KEY \
CLIENT_ID=$CLIENT_ID \
CLIENT_SECRET=$CLIENT_SECRET \
DATABASE_URL=$DATABASE_URL \
REDIRECT_URI=$REDIRECT_URI \
VATSIM_API_KEY=$VATSIM_API_KEY

# Install dependencies only when needed
FROM base 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

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

ENV BOT_WEBHOOK_API_KEY=$BOT_WEBHOOK_API_KEY \
CLIENT_ID=$CLIENT_ID \
CLIENT_SECRET=$CLIENT_SECRET \
DATABASE_URL=$DATABASE_URL \
REDIRECT_URI=$REDIRECT_URI \
VATSIM_API_KEY=$VATSIM_API_KEY

# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
COPY prisma ./prisma/
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi


# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

ENV BOT_WEBHOOK_API_KEY=$BOT_WEBHOOK_API_KEY \
CLIENT_ID=$CLIENT_ID \
CLIENT_SECRET=$CLIENT_SECRET \
DATABASE_URL=$DATABASE_URL \
REDIRECT_URI=$REDIRECT_URI \
VATSIM_API_KEY=$VATSIM_API_KEY

# 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 during the build.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN \
if [ -f yarn.lock ]; then yarn run build; \
elif [ -f package-lock.json ]; then npm run build; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
else echo "Lockfile not found." && exit 1; \
fi

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

ENV BOT_WEBHOOK_API_KEY=$BOT_WEBHOOK_API_KEY \
CLIENT_ID=$CLIENT_ID \
CLIENT_SECRET=$CLIENT_SECRET \
DATABASE_URL=$DATABASE_URL \
REDIRECT_URI=$REDIRECT_URI \
VATSIM_API_KEY=$VATSIM_API_KEY

ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1

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

COPY --from=builder /app/public ./public

# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
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

# server.js is created by next build from the standalone output
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
CMD HOSTNAME="0.0.0.0" node server.js
FROM node:18-alpine AS base

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

ENV BOT_WEBHOOK_API_KEY=$BOT_WEBHOOK_API_KEY \
CLIENT_ID=$CLIENT_ID \
CLIENT_SECRET=$CLIENT_SECRET \
DATABASE_URL=$DATABASE_URL \
REDIRECT_URI=$REDIRECT_URI \
VATSIM_API_KEY=$VATSIM_API_KEY

# Install dependencies only when needed
FROM base 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

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

ENV BOT_WEBHOOK_API_KEY=$BOT_WEBHOOK_API_KEY \
CLIENT_ID=$CLIENT_ID \
CLIENT_SECRET=$CLIENT_SECRET \
DATABASE_URL=$DATABASE_URL \
REDIRECT_URI=$REDIRECT_URI \
VATSIM_API_KEY=$VATSIM_API_KEY

# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
COPY prisma ./prisma/
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi


# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

ENV BOT_WEBHOOK_API_KEY=$BOT_WEBHOOK_API_KEY \
CLIENT_ID=$CLIENT_ID \
CLIENT_SECRET=$CLIENT_SECRET \
DATABASE_URL=$DATABASE_URL \
REDIRECT_URI=$REDIRECT_URI \
VATSIM_API_KEY=$VATSIM_API_KEY

# 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 during the build.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN \
if [ -f yarn.lock ]; then yarn run build; \
elif [ -f package-lock.json ]; then npm run build; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
else echo "Lockfile not found." && exit 1; \
fi

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

ENV BOT_WEBHOOK_API_KEY=$BOT_WEBHOOK_API_KEY \
CLIENT_ID=$CLIENT_ID \
CLIENT_SECRET=$CLIENT_SECRET \
DATABASE_URL=$DATABASE_URL \
REDIRECT_URI=$REDIRECT_URI \
VATSIM_API_KEY=$VATSIM_API_KEY

ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1

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

COPY --from=builder /app/public ./public

# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
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

# server.js is created by next build from the standalone output
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
CMD HOSTNAME="0.0.0.0" node server.js
Solution:
something real funky is going on with your project, try just running normal next start
Jump to solution
123 Replies
Percy
Percy4mo ago
Project ID: 19953c85-3aed-4faa-989e-4fb6c0b9d816
Sam
Sam4mo ago
19953c85-3aed-4faa-989e-4fb6c0b9d816 Turns out what i said previously did not fix it, I've removed the solved tag for now
Brody
Brody4mo ago
Try without the ARG to ENV assignments
Sam
Sam4mo ago
hey, yeah I tried that but it didn't seem to work I'll try and do it again but it doesn't look like it worked the first time
Brody
Brody4mo ago
please do, regardless if it does or doesn't work, it's not needed so it's good to rule it out anyway
Sam
Sam4mo ago
yeah thats the thing, I had tried that initially and it looked like it was working until i got a message from someone using the service and it turned out it wasn't so 🤷‍♂️ , redeploying now
Brody
Brody4mo ago
also probably a good idea to remove the EXPOSE and ENV PORT lines too
Sam
Sam4mo ago
will do, yeah doesn't look like this worked unfortunately
Brody
Brody4mo ago
does a standalone next build require variables to be prefixed with something? like NEXT_?
Sam
Sam4mo ago
It's strange, the environment variables are being passed on buildtime but not runtime only when being used in client components
Brody
Brody4mo ago
variables are most certainly being passed at runtime, there's just something simple we are overlooking here
Sam
Sam4mo ago
but in the cases where I'm using my env vars, no, as it is code being ran on the server rather than the client
Brody
Brody4mo ago
and you're sure the environment variables that are missing aren't trying to be statically built into the code?
Sam
Sam4mo ago
i mean they shouldn't be, it was working fine when i was using the default nixpacks i just wanted to use docker so i could specify an image that isn't as RAM intensive
Brody
Brody4mo ago
nixpacks includes every single service variable you have as an ARG in its generated dockerfile, so that may explain why it works so try to specify all your environmental variables as ARGs in the correct layer of your dockerfile
Sam
Sam4mo ago
but i'm specifying all of them in every layer, surely they should be available then? unless i'm misunderstanding how dockerfiles work 😂
Brody
Brody4mo ago
you only have 6 service variables?
Sam
Sam4mo ago
yes
Sam
Sam4mo ago
No description
Brody
Brody4mo ago
okay this is getting strange, have you tried a simple console log in the backend for some of those environment variables?
Sam
Sam4mo ago
i know for sure that the DATABASE_URL and CLIENT_ID variables are not being passed based on my deploy logs and through my OAuth login where it's setting one of the URL params as &client_id=undefined from that i'd say it's safe to assume that none of the environment variables are being set properly
Brody
Brody4mo ago
would you happen to be committing an .env file to GitHub?
Sam
Sam4mo ago
i'm committing an .env.example, but no i'm not committing a .env file
Brody
Brody4mo ago
is your code trying to somehow load the .env.example?
Sam
Sam4mo ago
i highly doubt it, that's never happened before and like i said the environment variables are working fine in build time where i know at least DATABASE_URL is being used luckily for now i can just rollback to the nixpacks build but it would be nice to get a Dockerfile working
Brody
Brody4mo ago
definitely something simple we are overlooking here I'll try to reproduce
Sam
Sam4mo ago
very likely, unfortunately the documentation isn't very detailed on what happens with environment variables when using Dockerfiles
Brody
Brody4mo ago
the docs do actually cover how to use environment variables during the build, and during runtime there is nothing you need to do because service variables are automatically injected into the containers environment
Sam
Sam4mo ago
in that case, let me try not setting ARG in the runner layer maybe they're conflicting
Brody
Brody4mo ago
ARG is short for build arguments, they shouldn't be put into the environment of the built image, but I've seen stranger things
Sam
Sam4mo ago
that very well could be it then, new to docker here 😂 nope, still not being set however i could still be right, let me remove the ARGs from the base layer as well
Brody
Brody4mo ago
they should only be needed in the layer that runs commands that use the environment variables
Sam
Sam4mo ago
does the ARG command actually set it as an environment variable though? or as a variable inside of the docker file, because technically the DATABASE_URL isn't being used inside of the dockerfile itself, it just needs to be set in order for prisma to generate types okay looks like that worked! removing it from the base layer and only setting it in the layers where they're needed fixed it it looks like that anyways ugh wait no i spoke too soon
Brody
Brody4mo ago
ARG is short for build arguments, specifying them brings the build arguments into the build but not the runtime, railway when building from the dockerfile will specify all service variables as build arguments
Sam
Sam4mo ago
I'm not quite sure here then, the environment variables are being set fine during the build because next.js is building fine, but then when it gets to runtime they no longer seem to be set
Brody
Brody4mo ago
yes I am currently stumped here too just for debugging purposes, can you change your dockerfile to only use a single FROM?
Sam
Sam4mo ago
FROM node:18-alpine AS base

# Install dependencies only when needed
FROM base 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

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
COPY prisma ./prisma/
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi


# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

# 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 during the build.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN \
if [ -f yarn.lock ]; then yarn run build; \
elif [ -f package-lock.json ]; then npm run build; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
else echo "Lockfile not found." && exit 1; \
fi

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1

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

COPY --from=builder /app/public ./public

# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

# server.js is created by next build from the standalone output
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
CMD HOSTNAME="0.0.0.0" node server.js
FROM node:18-alpine AS base

# Install dependencies only when needed
FROM base 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

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
COPY prisma ./prisma/
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi


# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

# 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 during the build.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN \
if [ -f yarn.lock ]; then yarn run build; \
elif [ -f package-lock.json ]; then npm run build; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
else echo "Lockfile not found." && exit 1; \
fi

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1

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

COPY --from=builder /app/public ./public

# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

# server.js is created by next build from the standalone output
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
CMD HOSTNAME="0.0.0.0" node server.js
that's what i've got currently shall i just remove all of the instances of FROM? apart from the first one of course
Brody
Brody4mo ago
haha no you don't yep that's what I meant!
Sam
Sam4mo ago
sorry as in that^^^ is what i've got in my dockerfile currently
Brody
Brody4mo ago
ah gotcha, I see what you meant
Sam
Sam4mo ago
ugh docker doesn't like my dockerfile give me a sec
Brody
Brody4mo ago
so yeah try with only a single FROM and of course remove all the copy stuff and for extra good measure, no user / chown stuff either basically we want the most barebones dockerfile, then if we get that working, you can start adding the fancy stuff back for process of elimination
Sam
Sam4mo ago
yeah i removed all of the copy stuff but docker has it all cached and it's a bit screwy give me a sec
Brody
Brody4mo ago
set NO_CACHE to 1
Sam
Sam4mo ago
apologies, where do i set that?
Brody
Brody4mo ago
service variables
Sam
Sam4mo ago
ah alright right it's building now will keep you updated woah the docker image is so much bigger? it's gone from like 60-70MB to 600?
Brody
Brody4mo ago
yeah thats the joys of not using a multi stage image haha, but thats too be expected
Sam
Sam4mo ago
i'm struggling even getting this dockerfile to work currently
FROM node:18-alpine

RUN apk add --no-cache libc6-compat
WORKDIR /app

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
COPY prisma ./prisma/
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi

COPY . .

RUN \
if [ -f yarn.lock ]; then yarn run build; \
elif [ -f package-lock.json ]; then npm run build; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
else echo "Lockfile not found." && exit 1; \
fi

ENV NODE_ENV production

CMD HOSTNAME="0.0.0.0" node server.js
FROM node:18-alpine

RUN apk add --no-cache libc6-compat
WORKDIR /app

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
COPY prisma ./prisma/
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi

COPY . .

RUN \
if [ -f yarn.lock ]; then yarn run build; \
elif [ -f package-lock.json ]; then npm run build; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
else echo "Lockfile not found." && exit 1; \
fi

ENV NODE_ENV production

CMD HOSTNAME="0.0.0.0" node server.js
do i need to do something special here actually i might be missing a copy . . after the build step
Brody
Brody4mo ago
what package manager do you use locally?
Sam
Sam4mo ago
pnpm, i should probably remove that complicated code as well oh well no worries, lets see if that COPY . . i added sorted it
Brody
Brody4mo ago
then youd only want to copy in package.json and pnpm-lock.yaml in the first COPY
Sam
Sam4mo ago
i really dislike docker sometimes 😂
Brody
Brody4mo ago
haha well whats the status on the missing environment variables?
Sam
Sam4mo ago
honestly still haven't got this dockerfile working properly 😂 so i was getting an error that /app/server.js wasn't found, which making sense because i removed the COPY commands that copied those files over
Brody
Brody4mo ago
simplify it more
Sam
Sam4mo ago
FROM node:18-alpine

RUN apk add --no-cache libc6-compat
WORKDIR /app

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

COPY package.json pnpm-lock.yaml* ./
COPY prisma ./prisma/
RUN corepack enable pnpm && pnpm i --frozen-lockfile

COPY . .

RUN pnpm run build

COPY . .

COPY /app/public ./public

COPY /app/.next/standalone ./
COPY /app/.next/static ./.next/static

ENV NODE_ENV production

CMD HOSTNAME="0.0.0.0" node server.js
FROM node:18-alpine

RUN apk add --no-cache libc6-compat
WORKDIR /app

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

COPY package.json pnpm-lock.yaml* ./
COPY prisma ./prisma/
RUN corepack enable pnpm && pnpm i --frozen-lockfile

COPY . .

RUN pnpm run build

COPY . .

COPY /app/public ./public

COPY /app/.next/standalone ./
COPY /app/.next/static ./.next/static

ENV NODE_ENV production

CMD HOSTNAME="0.0.0.0" node server.js
and i added them back but because its caching even though i set NO_CACHE to 1 those folders don't exist technically
Brody
Brody4mo ago
what makes you think its caching still?
Sam
Sam4mo ago
No description
Brody
Brody4mo ago
show me how you have set that variable please
Sam
Sam4mo ago
ah apologies, doesn't look like i set the variable correctly oh but it's still cached
Brody
Brody4mo ago
^
Sam
Sam4mo ago
No description
Brody
Brody4mo ago
and now it still says CACHED?
Sam
Sam4mo ago
yes
Brody
Brody4mo ago
hmmm odd
Sam
Sam4mo ago
right i think i understood why it wasn't working
Brody
Brody4mo ago
do tell!
Sam
Sam4mo ago
basically i'm a noob at docker and there's a difference between what COPY and COPY --from does anyways just waiting for it to build now
Brody
Brody4mo ago
oh haha i thought you meant you found out why the runtime envs weren't working
Sam
Sam4mo ago
oh nope not yet haha but i think i've got a minimal dockerfile working at this point so we can work from here just waiting for the build
FROM node:18-alpine

RUN apk add --no-cache libc6-compat
WORKDIR /app

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

COPY package.json pnpm-lock.yaml* ./
COPY prisma ./prisma/
RUN corepack enable pnpm && pnpm i --frozen-lockfile

COPY . .

RUN pnpm run build

RUN cp -r /app/.next/standalone/* ./

ENV NODE_ENV production

CMD HOSTNAME="0.0.0.0" node server.js
FROM node:18-alpine

RUN apk add --no-cache libc6-compat
WORKDIR /app

ARG BOT_WEBHOOK_API_KEY
ARG CLIENT_ID
ARG CLIENT_SECRET
ARG DATABASE_URL
ARG REDIRECT_URI
ARG VATSIM_API_KEY

COPY package.json pnpm-lock.yaml* ./
COPY prisma ./prisma/
RUN corepack enable pnpm && pnpm i --frozen-lockfile

COPY . .

RUN pnpm run build

RUN cp -r /app/.next/standalone/* ./

ENV NODE_ENV production

CMD HOSTNAME="0.0.0.0" node server.js
this is as minimal of a dockerfile as i can give you and the environment variables still are not being passed through it's very very weird
Brody
Brody4mo ago
can you show me how you are accessing these environment variables in code?
Sam
Sam4mo ago
Literally just through process.env.<ENVIRONMENT_VARIABLE> as i said it's worked pretty much everywhere else except using Dockerfiles
Brody
Brody4mo ago
okay ill try to reproduce
Sam
Sam4mo ago
cheers
Brody
Brody4mo ago
works fine
No description
No description
No description
Brody
Brody4mo ago
obviously an extremely simplified test, but this working means this isnt a platform issue
Sam
Sam4mo ago
i've got absolutely no idea why this isn't working then 😂
Brody
Brody4mo ago
try doing something like this
CMD echo ${variable name here}; node server.js
CMD echo ${variable name here}; node server.js
Sam
Sam4mo ago
yeah i'm actually gonna see if it's being passed down in code just putting a console.log
Brody
Brody4mo ago
do both things
Sam
Sam4mo ago
okay now thats super strange this works but the code doesn't now i'm super confused 😂
Brody
Brody4mo ago
share your repo? theres a slim chance something sticks out to me
Sam
Sam4mo ago
would you mind if i added you to the repo? i don't mind you having a look at the code but i can't make the repo public right now
Brody
Brody4mo ago
for sure, body192
Sam
Sam4mo ago
i've invited you
Brody
Brody4mo ago
looking welp i have missspelt my own name my r key is going bad on my keyboard my gh username is brody192
Sam
Sam4mo ago
Oops 😂😂
Brody
Brody4mo ago
my bad
Sam
Sam4mo ago
gotcha now :)
Brody
Brody4mo ago
got it
Brody
Brody4mo ago
feels
No description
Sam
Sam4mo ago
yuuuppppp we all go through it once in a while don't worry about having to blur anything out in screenshots btw i'm not that bothered, the repo just can't be publically accessible haha
Brody
Brody4mo ago
so just to be clear, that echo in your start command does work?
Sam
Sam4mo ago
yep! which is honestly why i'm so confused even more than before 😂
Brody
Brody4mo ago
now what would a google search for "nextjs cant read environment variables" come up with haha, since we have ruled out a platform issue and for fun, can you delete the .env.example file
Sam
Sam4mo ago
yep can do
Sam
Sam4mo ago
GitHub
Standalone build does not include server-side variables from `.env....
Verify canary release I verified that the issue exists in the latest Next.js canary release Provide environment information Operating System: Platform: darwin Arch: arm64 Version: Darwin Kernel Ver...
Sam
Sam4mo ago
now granted, this is coming from .env but it's interesting
Brody
Brody4mo ago
try this?
No description
Sam
Sam4mo ago
i would but this doesn't fix the issue with prisma
Brody
Brody4mo ago
true, doesnt work for env()
Sam
Sam4mo ago
is it possible that prisma can only read from .env files?
Brody
Brody4mo ago
prisma is definitely able to read from the environment directly, something funky is going on here and I'm not sure what
Sam
Sam4mo ago
i'm going to try explicitly setting DATABASE_URL in the dockerfile
Brody
Brody4mo ago
as an ENV?
Sam
Sam4mo ago
yes at this point i'm trying anything 😂 still nope curiously it seems to fail when one the API routes is being hit there's an API route that gets hit every minute by our discord bot
Solution
Brody
Brody4mo ago
something real funky is going on with your project, try just running normal next start
Sam
Sam4mo ago
yep will do and honestly after this if it doesn't work i'll just go back to nixpacks the extra 4$ isn't worth it anymore 😂 erm wtf? so running pnpm start just works? ffs
Brody
Brody4mo ago
so next start works
Sam
Sam4mo ago
there must be some sort of bug with standalone it looks like it i can hit that API endpoint just fine well then thanks for all your help
Brody
Brody4mo ago
what a fun debug process!
Sam
Sam4mo ago
maybe for you 😂
Brody
Brody4mo ago
now you can go back to that mutli layer dockerfile!
Sam
Sam4mo ago
yep, i might file an issue on the next.js repo for this, it's a pretty weird bug
Brody
Brody4mo ago
watch them blame the platform haha
Sam
Sam4mo ago
anyways mate, thanks for sticking with me through this whole thing 😂
Brody
Brody4mo ago
happy to help!
Sam
Sam4mo ago
well now i know for sure it can't be that haha anyways marking this as solved, cheers!
Sam
Sam4mo ago
oh my god @Brody i just realized i bet this is because i'm on a relatively older version of next.js and there was a PR that literally fixes this exact issue like 1 or 2 patch versions later UGHHHH oh well
Brody
Brody4mo ago
lmao learn javascript they said, it will be fun they said
Sam
Sam4mo ago
GitHub
fix process.env not being available in standalone mode (#54203) · v...
What? When running Next in standalone mode, process.env is not made available to the render workers, making it impossible to access environment variables that aren&#39;t provided in `....
Brody
Brody4mo ago
haha simple fix too