#Docker standalone build inlining non NEXT_PUBLIC environment variables

5 messages · Page 1 of 1 (latest)

digital raptor
#

I am trying to build a docker image, but next build keeps trying to read and even execute the code that uses the CONNECTION_STRING environment variable at build time.

I tried:

  1. Placing it into another variable:
    const connectionString = process.env.CONNECTION_STRING;
  2. Throwing an error when the environment variable is not present:
    if (!connectionString) {
    throw new Error('Please add your Mongo connection string to .env.local');
    }
  3. Making a function that reads the variable:
    const getEnvironmentVariable = (name: string): string => {
    const value = process.env[name];
    if (!value) {
    throw new Error(Missing environment variable: ${name});
    }
    return value;
    };

and a few other tricks, none of which helped. I am dumbstruck that even when I managed to get past the "environment variable missing", I got an error instantiating the MongoClient:

new MongoClient(connectionString!, options)

Another thing to note is, that, when I deleted all of my app/api/<some_route>/route.ts files, which were using the mongo client, then the error went away, while I'm still using the client in NextAuth:

import mongoClient from '@/connectors/mongodb';

`...

callbacks: {
    async signIn({ user }) {
        const client = await mongoClient;
        const dbUser = await client
            .db()
            .collection<{ role: string }>('users')
            .findOne({ email: user.email });

        if (!dbUser) return false;

        return true;
    },
},

...

Note that my NextAuth is set up in the pages folder, not the app folder.

So now I am absolutely stumped as to why the build insists so much on inlining what quite obviously to me should not be inlined as is documented as though it will not be inlined here:

https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables

and is not used at all on the client side.

Help? sweating

Learn to add and access environment variables in your Next.js application.

river geyserBOT
#

🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord

🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize

✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)

digital raptor
#

I'd also like to note that I couldn't find a correct answer using Next documentation, Google search or any of the four available AI chatbots I have available, including the premium ChatGPT.

#

Another note: I'm basically using Next examples for a production dockerfile:

FROM node:alpine AS base

FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci

FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

RUN npm run build

FROM base AS runner
WORKDIR /app

ENV NODE_ENV production

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

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

RUN mkdir .next
RUN chown nextjs:nodejs .next

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

USER nextjs

ENV HOSTNAME "0.0.0.0"

CMD ["node", "server.js"]

And mongoClient:

import { MongoClient } from 'mongodb';

const options = {};

let client;
let clientPromise: Promise<MongoClient>;

const connectionString = ${process.env.CONNECTION_STRING}/${process.env.DATABASE_NAME}?retryWrites=true&w=majority;

if (process.env.NODE_ENV === 'development') {
let globalWithMongo = global as typeof globalThis & {
_mongoClientPromise?: Promise<MongoClient>;
};

if (!globalWithMongo._mongoClientPromise) {
    client = new MongoClient(connectionString, options);
    globalWithMongo._mongoClientPromise = client.connect();
}
clientPromise = globalWithMongo._mongoClientPromise;

} else {
client = new MongoClient(connectionString, options);
clientPromise = client.connect();
}

export default clientPromise;

vivid wharf
#

I'm facing the exact same issue. Using output: 'standalone' , I cannot override server only env params from the docker run command.

All env params appear to be inlined regardless of the NEXT_PUBLIC prefix being present or not.