Better support for runtime environment variables. #44628
-
Describe the feature you'd like to requestWhen dealing with Docker based deployments on different environments, it's very useful to be able to specify environment variables for thinks like the base url for api calls, or a token for a analytics service. Currently, it seems that next.js only properly supports specifying environment variables at build time, this leads to the following issue when using Docker.
Describe the solution you'd likeI think there are type of environment variable that need to able to override:
Being able to override the environment variables runtime would solve the first problem, but additional work on the server side render is probably also needed to support these cases properly. Describe alternatives you've consideredAn alternative would be to build specific Docker images for specific environments, however. I think this is considered an anti-pattern and should preferably be avoided. |
Beta Was this translation helpful? Give feedback.
Replies: 24 comments 62 replies
-
To continue this discussion here: I full agree to the input/request from @svenvandescheur . We're deploying our application to different environments which have a variety of different configurations (endpoints, tokes etc.). The solution right now results in building many identical images in the pipeline with different build args. One build runs 15min including the upload to the registry. With every environment we're adding, we add 15min build time (or resources if run in parallel). This is a mess. For other client side only projects the solution is straight forward. We're using an nginx proxy with |
Beta Was this translation helpful? Give feedback.
-
Another post in agreement - I'm new to Next.js and was surprised to find it does not support runtime environment variables, as they're a common best-practice pattern for building modern 12 factor apps and/or those deployed via Docker. A big selling point of using Docker to begin with is to be able to build one image and have it work everywhere - dev, test, staging, production, etc - and having to "bake" in environment-specific configuration at build-time is antithetical to that goal. Speaking of my specific deployment process for a backend service as an example of what I'd expect, I use AWS secrets manager to store and manage access to various environment configurations which then get injected into the docker environment at runtime using ECS + Fargate (though this could be any orchestrator). Doing it this way both lets me easily set up any number of arbitrary environments/configurations and control access to sensitive configuration info (e.g. API keys, database credentials, etc), only allowing a given container instance access to the config it needs to run and restricting access everywhere else. Versus if it is baked into the image, anyone who has access to pull that image also has access to that "baked in" information (and rotation of secrets always requires a rebuild of the image), and in order to build the image, there needs to be a build machine that has access to that configuration info (realistically probably for all environments unless you have a separate build machine for every environment) so that it can generate a .env file for a given environment. Additionally I also can't build a "production" image on my local machine (say I'm troubleshooting something or the build machine goes down) without placing production credentials on my local machine. So now I have potentially sensitive info in a few places (the image, the build machine, a local machine) that needs to be managed. Build-time variables make sense when they're not sensitive and don't vary by environment, but are really problematic and clumsy for anything else. As I said, I am new to Next, so if there's just some functionality I missed or I misunderstood the environment variable docs, I'd love to hear about it. Otherwise has anyone come up with a solution that doesn't involve creating multiple image variants when the server-side env varies? |
Beta Was this translation helpful? Give feedback.
-
I ran into this months ago with a React Application. Since the build ends in static pages (in my case, served by nginx) there was no way to overcome this problem. However, I found a useful workaround (similar to the one described here: https://www.freecodecamp.org/news/how-to-implement-runtime-environment-variables-with-create-react-app-docker-and-nginx-7f9d42a91d70/) This week, I'm working on automating my building process for a new project and I found that next.js is not solving this out of the box (as I thought it would, since there is some great treatment of variables). I think I'm going to implement something similar. The downside here is that I will have variables in the process.env for the server, others in the process.env for the browser, and my own window.env that would be the ones not needed during the building process, available in the front. My usecase: I want to initialize the firebase/app client-side (using the public API KEY, of course). If I use the process.env.* that is required on build time. -- Any thoughts on that? |
Beta Was this translation helpful? Give feedback.
-
I have the same issue. I am building a CI/CD pipeline and I want to have a "development" environment running locally, a "test" environment for staging, and a "production" environment for production. I have looked all over in obscure blogs and discussions and I have tried the getConfig() methods of doing it and it still doesn't work, because with NextJS.13 we don't use getServerSideProps or getInitialProps or whatever. So I think I have to literally build two different images where the ONLY difference between them is the environment variables. One for the test environment and one to findally deploy to production. This is instead of just building one single image and just piping in the environment variables at runtime... What's worse is I am using AWS App Runner (at least for now), so it should be super easy, I just set the environment variables in the AWS console, but this small yet significant oversight makes the workflow impossible. I do not see why the environment variables need to be "rendered" into plain text or whatever the issue is. |
Beta Was this translation helpful? Give feedback.
-
Hi! 👋 We've created a package that adds support for runtime variables in Next.js: https://github.com/expatfile/next-runtime-env. Feel free to give it a try! 😉 |
Beta Was this translation helpful? Give feedback.
-
This is awersome!
I have applied the same solution. I'm wondering why I didn't publish that.
Shame on me.
Count me in as a maintainer.
--
*Norberto L. Herz*
norbertoherz.com
[image: https://www.linkedin.com/pub/norberto-herz/5/887/177]
<https://www.linkedin.com/pub/norberto-herz/5/887/177>
<https://twitter.com/nohorbee> <https://www.facebook.com/nohorbee>
*"Peace cannot be kept by force. It only can be achieved by understanding"
- Albert Einstein*
…On Sun, Apr 30, 2023 at 2:16 PM Zino Hofmann ***@***.***> wrote:
Hi! 👋
We've created a package that adds support for runtime variables in
Next.js: https://github.com/expatfile/next-runtime-env.
Feel free to give it a try! 😉
—
Reply to this email directly, view it on GitHub
<#44628 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AARK7G4YUKN5KAUXOHYE5GDXD2M5NANCNFSM6AAAAAAT6IVT5Y>
.
You are receiving this because you commented.Message ID: <vercel/next.
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Good that this is being discussed at least. I used NextJS in one application last year and now again using it. Unfortunately, I picked up the App router. And any of the solutions that are being discussed in various forums are not working with App router. And I don't why the solutions are not working when the official documentation clearly says that it should work. This is the note from official documentation,
source: https://nextjs.org/docs/app/building-your-application/configuring/environment-variables Note the last sentence. It clearly says that we can acces runtime variables via API. So I create following API, // src/app/api/env/route.ts
import { NextResponse } from 'next/server';
export async function GET() {
return NextResponse.json({
API_BASE_URL: process.env.API_BASE_URL,
// Add other environment variables you want to expose here
});
} But this API is still returning the values set at build time. No runtime values. Did I misunderstand the documentation? It states that runtime environment variables can be accessed via an API, but my experience suggests otherwise. Could someone clarify this part of the documentation? |
Beta Was this translation helpful? Give feedback.
-
I came up with a partial solution for this issue. Disclaimer: This doesn't completely solve the problem of having real runtime environment variables since you still need to restart your server to apply the changes made to the env vars, but this has worked nicely for our team because we don't have any issue restarting the server and is almost instant even for bigger projects. The idea is to take advantage of the server-side rendering made by Next.js since NEXT_PUBLIC_ prefixed variables are replaced with the hardcoded value during build time, this is not an option and you should avoid using this naming convention for the environment variables you want to make "restart-time". For projects using the App Directory:For this to work you need your root layout (or anywhere you use the env provider) to be server-side First, we create an Environment Provider for our app:
Next, we feed the env provider with our environment variables object
To access your env vars, you'd do it as follows:
Reading the .env fileAs the final step, you should copy your env file to your build (.next) directory, if using the standalone output copy the file to And now you are all set, you build once, and whenever you need to change an env var value you change it and restart your server. Let me know your thoughts about this, I'm completely open to feedback, and if you come up with a better solution I would like to know! Thank you for taking the time to read my semi-solution! |
Beta Was this translation helpful? Give feedback.
-
Just want to give my experience. I am trying to follow the "build once deploy anywhere" principle. This means that we only get to build our application once and we must use the exact same image to deploy to dev, staging, prod, etc. The consequence of this is that we must read from environment variables at run-time (not build-time). I have read through the following discussions and have attempted every solution in them. Many of the solutions work if you are using the Pages Router, but do not work with Next.js 13 and the App Router. In the end, I found three possible approaches, all of which are less than ideal:
|
Beta Was this translation helpful? Give feedback.
-
This is a huge issue. Very annoying. |
Beta Was this translation helpful? Give feedback.
-
As a workaround I find and replace env vars at runtime inside of an NX.dev monorepo. I am using NextJS 13: "next": "^13.4.16", Dockerfile: # Install dependencies only when needed
FROM node:version AS deps
ARG MICROFRONTEND_NAME=name
ARG NEXT_APPLICATION_BUILD_FOLDER=dist/apps/$MICROFRONTEND_NAME
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY ${NEXT_APPLICATION_BUILD_FOLDER}/package.json /app/
RUN npm i
# Production image, copy all the files and run next
FROM node:version AS runner
WORKDIR /app
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
ENV NODE_ENV production
ARG MICROFRONTEND_NAME=name
ARG NEXT_APPLICATION_BUILD_FOLDER=dist/apps/$MICROFRONTEND_NAME
COPY ${NEXT_APPLICATION_BUILD_FOLDER}/public ./public
COPY --chown=nextjs:nodejs ${NEXT_APPLICATION_BUILD_FOLDER}/.next ./.next
COPY --chown=nextjs:nodejs ${NEXT_APPLICATION_BUILD_FOLDER}/.nx-helpers ./.nx-helpers
COPY --from=deps /app/node_modules ./node_modules
COPY ${NEXT_APPLICATION_BUILD_FOLDER}/package.json ./package.json
COPY ${NEXT_APPLICATION_BUILD_FOLDER}/next.config.js ./next.config.js
COPY entrypoint.sh ./entrypoint.sh
RUN chmod +x entrypoint.sh
RUN echo "Checking built files..." && \
ls -al /app/.next && \
ls -al /app/public && \
cat /app/package.json && \
cat /app/next.config.js
USER nextjs
EXPOSE 3000
ENV PORT 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
ENTRYPOINT ["/app/entrypoint.sh"] entrypoint.sh: #!/bin/sh
set -e
# Display an error message and exit
fail() {
echo "$1" >&2
exit 1
}
echo "Check that we have NEXT_PUBLIC_API_URL vars $NEXT_PUBLIC_API_URL for environment $NEXT_PUBLIC_ENV"
[ -z "$NEXT_PUBLIC_API_URL" ] && fail "Error: NEXT_PUBLIC_API_URL is not set!"
# Replace placeholders in /app/.next with actual NEXT_PUBLIC_API_URL
# Skip .git directories
find /app/.next -type f ! -path '*/.git/*' -print0 | xargs -0 sed -i "s#APP_NEXT_PUBLIC_API_URL#$NEXT_PUBLIC_API_URL#g"
find /app/.next -type f ! -path '*/.git/*' -print0 | xargs -0 sed -i "s#APP_NEXT_PUBLIC_ENV#$NEXT_PUBLIC_ENV#g"
echo "Starting Nextjs"
echo "Running command: $@"
exec "$@" Then I inject the runtime environment variables using ECS via the AWS CDK. new WebV2Stack(this, 'Web', {
webName: 'name',
environment,
priority: 2,
environmentVariables: {
NEXT_PUBLIC_ENV: environment,
NEXT_PUBLIC_API_URL: `https://${
environment === 'production' ? '' : `${environment}.`
}api.com`,
},
...
});
}
...
const container = taskDefinition.addContainer(
`${capitalize(props.webName)}`,
{
image,
containerName: `${props.webName}-task`,
memoryLimitMiB: 256,
...
environment: props.environmentVariables || {},
command: [
`node_modules/.bin/next`,
'start',
],
}
); This seems to work when I spin up the container in ECS. It takes ~10-30 seconds to do the entrypoint find/replace but works as expected. I would much prefer I didn't have to do the find and replace though. The ultimate goal is to build once and deploy to multiple environments. This ensures the bits/bytes are the same for different environments with the only change being the API we point to or the environment name. |
Beta Was this translation helpful? Give feedback.
-
Next.js can support both build time and runtime environment variables. By default, environments variables are only available on the server. To expose an environment variable to the browser, it must be prefixed with To read runtime environment variables, we recommend incrementally adopting the App Router. With the App Router, we can safely read environment variables on the server during dynamic rendering. This allows you to use a singular Docker image that can be promoted through multiple environments with different values. // This is as of Next.js 14, but you could also use other dynamic functions
import { unstable_noStore as noStore } from 'next/cache';
export default function Component() {
noStore(); // Opt into dynamic rendering
// This value will be evaluated at runtime
const value = process.env.MY_VALUE
...
} Good to know:
|
Beta Was this translation helpful? Give feedback.
This comment was marked as off-topic.
This comment was marked as off-topic.
-
All great comments from the community. Proper support of runtime environment variables should be top priority for NextJs. Currently hacky approaches are required to work with docker. |
Beta Was this translation helpful? Give feedback.
-
That I cannot just drop NextJS into Google Cloud Run and configure the environmental variables and secrets properly is insane. |
Beta Was this translation helpful? Give feedback.
-
Hey everyone – we have just published new documentation on self-hosting, including how to configure a custom cache handler for use with ISR / Data Cache in both the Pages and App Router. These docs go in depth about how other features like Image Optimization, Middleware, Environment Variables, Build Caching, and more work when self-hosted. There's also updated Docker based examples. Specific to this discussion, we have provided guidance on how to use runtime environment variables. https://nextjs.org/docs/app/building-your-application/deploying |
Beta Was this translation helpful? Give feedback.
-
Just to throw a solution here, I have a particular setup for my self-hosted Next project, but I managed to solve it with the app router (v14.0.1), here are the key aspects of the setup:
The environment variables are read from an external config file, which is read and injected into the Kubernetes container that then injects it into the pod running the What we did is read those variables during server-side rendering and expose them to the client using script tags and the // app/layout.tsx
export default function Layout({ children }: { children: ReactNode }) {
return (
<html lang="en">
<head>
<RscPublicEnvironmentVariablesScript />
</head>
<body>{children}</body>
</html>
);
} // app/RscPublicEnvironmentVariablesScript.tsx
export function RscPublicEnvironmentVariablesScript() {
const headersList = headers();
const nonce = headersList.get('x-nonce') ?? '';
const environmentVariables: EnvironmentVariables = Object.entries(process.env).reduce<EnvironmentVariables>(
(accum, [key, value]) => {
if (key.includes('NEXT_PUBLIC_')) {
accum[key] = value;
}
return accum;
},
{},
);
return (
<script
nonce={nonce}
dangerouslySetInnerHTML={{
__html: `window.environment = ${JSON.stringify(environmentVariables)}`,
}}
/>
); This also makes sure to grab the nonce we set in Now we can use environment variables in functions, components and even on config files: // envirnomentVariables.ts
export const envirnomentVariables = {
MY_VAR: window.environment.MY_VAR
}
// a component
function Component() {
useEffect(() => {
fetch(window.environment.API_ENDPOINT);
}, []);
return (<div>component</div>)
} |
Beta Was this translation helpful? Give feedback.
-
This seemed very frustrating. But we ended up employing,
So, before starting the server, we change all the string with 'NEXT_PUBLIC_UI' with whatever we want. |
Beta Was this translation helpful? Give feedback.
-
This is still super broken, my route uses |
Beta Was this translation helpful? Give feedback.
-
@leerob any recommendations with incrementally migrating from pages to app router? Running into an issue when a lib with runtime values needs to run in pages and app, since we are moving our code bit by bit to app router. |
Beta Was this translation helpful? Give feedback.
-
hi guys, here is my workaround for Dockerized Next 14, using // src/lib/config.ts
import { NextResponse } from "next/server"
const isServer = typeof window === 'undefined';
const isClient = !isServer;
export const ENVIROMENT_VARIABLES_COOKIE = 'environment-variables';
export function registerEnvironmentCookies(response: NextResponse) {
if (isClient) {
console.error('This function can only be called from server side');
return response;
}
const environmentVariables: Record<string, string | undefined> = {
NEXT_PUBLIC_SUPABASE_URL: process.env.NEXT_PUBLIC_SUPABASE_URL,
'NEXT_PUBLIC_SUPABASE_ANON_KEY': process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
}
response.cookies.set({
name: ENVIROMENT_VARIABLES_COOKIE,
value: JSON.stringify(environmentVariables),
path: '/',
});
return response;
}
export function getEnvironmentVariable(name: string) {
if (isServer) {
console.error('This function can only be called from client side');
return;
}
const variablesStr = window.document.cookie
.split(';')
.find((cookie) => cookie.startsWith(`${ENVIROMENT_VARIABLES_COOKIE}=`))
?.split('=')
.at(1);
if (!variablesStr) {
return console.error('No environment variables found, did you called `registerEnvironmentCookies()`?');
}
const variables = JSON.parse(decodeURIComponent(variablesStr)) as Record<string, string | undefined>;
return variables[name];
} // src/middleware.ts
import type { NextRequest } from 'next/server'
import { NextResponse } from 'next/server'
import { registerEnvironmentCookies } from '@/lib/config';
export function middleware(_request: NextRequest) {
const response = NextResponse.next();
return registerEnvironmentCookies(response);
} Then I use it inside my client components "use client"
import { getEnvironmentVariable } from "@/lib/config";
export default function Home() {
cons supaUrl = getEnvironmentVariable('NEXT_PUBLIC_SUPABASE_URL');
return (
<main>
{ supaUrl }
</main>
);
} |
Beta Was this translation helpful? Give feedback.
-
This is another workaround import Script from 'next/script'
// Add this file to some Server Component, in my case I use this in `app/layout.tsx`
// Next.js, will inline all the process.env.SOMETHING variables into the code at build time.
// Which will force us to build the app for each environment we want to deploy to, with the
// only different being few environment variables. Instead, what we want is to get the environment
// dynamically from the runtime, so if we change them in the env and run the app again, it must
// use the new environment variables. To do this, we will inject the environment variables into
// the window object, so we can access them in the runtime.
// IMPORTANT: this can't be access with `process.env.SOMETHING`, as it will be replaced at build time,
// instead use the `getEnv` function from `env.tsx`.
const InjectRuntimePublicEnv = () => {
const env = Object.entries(process.env).reduce((all, [key, value]) => {
if (!key.startsWith('NEXT_PUBLIC_')) {
return all
}
all[key] = value
return all
}, {})
return (
<Script
id="inject-runtime-env"
strategy="beforeInteractive"
>{`window.process = ${JSON.stringify({ env }, null, 2)}`}</Script>
)
} and loader import { unstable_noStore as noStore } from 'next/cache'
export default function getEnv(name: string) {
noStore()
return process.env[name]
} |
Beta Was this translation helpful? Give feedback.
-
Bash ScriptCreate a script named #!/bin/sh
# Create a temporary directory for environment variable storage
TMP_DIR="/app/temp-v"
mkdir -p "$TMP_DIR"
# Create the __ENV.js file with the environment variables
echo "window.__ENV = {" > "$TMP_DIR/__ENV.js"
# Loop through environment variables starting with NEXT_PUBLIC_
for var in $(env | grep '^NEXT_PUBLIC_' | cut -d'=' -f1); do
value=$(printenv "$var")
key=$(echo "$var" | sed 's/^NEXT_PUBLIC_//')
echo " $key: '${value}'," >> "$TMP_DIR/__ENV.js"
done
# Close the JSON object
echo "};" >> "$TMP_DIR/__ENV.js"
# Copy the generated __ENV.js file to the public directory
cp "$TMP_DIR/__ENV.js" /app/public/
# Clean up the temporary directory
rm -rf "$TMP_DIR"
# Execute the application
exec "$@" DockerfileHere’s an example Dockerfile to build and run the application: # Base image for dependencies installation
FROM node:18-alpine AS base
WORKDIR /app
# Copy the project files into the /app directory
COPY . .
# Remove generate-env.sh for the build stage
RUN rm -rf generate-env.sh
# Build stage
FROM base AS builder
# Install dependencies and build the project
RUN npm run build
# Production image
FROM node:18-alpine AS runner
WORKDIR /app
# Create a non-root user
RUN addgroup --system --gid 1001 nodejs \
&& adduser --system --uid 1001 nextjs --ingroup nodejs
# Copy built files from the builder stage
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
# Copy the script and set permissions
COPY generate-env.sh /app/generate-env.sh
RUN chmod +x /app/generate-env.sh
# Change ownership of /app to the non-root user
RUN chown -R nextjs:nodejs /app
# Switch to the non-root user
USER nextjs
# Use ENTRYPOINT to run the script
ENTRYPOINT ["/app/generate-env.sh"]
# Default command to run the application
CMD ["sh", "-c", "HOSTNAME=0.0.0.0 PORT=3000 node ./server.js"] Docker Compose FileConfigure your version: '3.8'
services:
nextjs-app:
build:
context: .
dockerfile: ./Dockerfile
ports:
- "3000:3000"
environment:
NEXT_PUBLIC_KHIAR: test-env Integrating the Environment Variables in Next.jsIn your import { Html, Head, Main, NextScript } from "next/document";
import Script from "next/script";
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
<Script strategy="beforeInteractive" src="/__ENV.js" />
</body>
</Html>
);
} To use the environment variables in your components, you can utilize the import { env } from "next-runtime-env";
export default function Home() {
const env1 = env('KHIAR');
return (
<main>
{env1}
</main>
);
} the problem with next-run-time env is that it doesn't regenerate the env file inside the public directory when the container starts so move that part to a script in the docker |
Beta Was this translation helpful? Give feedback.
-
We were using sed method (#44628 (comment)) to have the same docker image in different environments. We had an inconsistency in the variable replacement in some parts of the code and the way we used and where we used process.env.NEXT_PUBLIC After a team member complained that some variables could be wrong after the build and replace, we did a little investigation in the generated chunks and found some replacements like process.env.VAR_VALUE We changed our process a little and it seems to be working fine now. We have a .env.production in the project as markup that is used during the build .env.production
We also have an entrypoint.sh that replaces the environment variables, the variables injected into the container when started. entrypoint.sh #!/bin/bash
set -e
# Function to display an error message and exit
fail() {
echo "$1" >&2
exit 1
}
# List of all environment variables
env_vars=(
"NEXT_PUBLIC_BASE_URL"
"NEXT_PUBLIC_NO_SECRET"
)
# Function to escape special characters in replacement strings for sed
escape_sed() {
echo "$1" | sed -e 's/[\/&]/\\&/g'
}
# Check if all environment variables are set
for var in "${env_vars[@]}"; do
value="${!var}"
echo "Checking that $var is set to '$value'"
[ -z "$value" ] && fail "Error: $var is not set!"
done
# Check if .env.production exists and remove it, let configMap to env only
if [ -f "/app/.env.production" ]; then
rm /app/.env.production
echo ".env.production file deleted."
else
echo "Skipping .env.production deletion as the file does not exist."
fi
# Create a temporary sed script
sed_script=$(mktemp)
# Ensure the temporary sed script is deleted on exit
trap 'rm -f "$sed_script"' EXIT
# Generate sed commands for each environment variable
for var in "${env_vars[@]}"; do
value="${!var}"
escaped_value=$(escape_sed "$value")
# Define the protected variable name by inserting __SAFE_LOCK__ after NEXT
# For example, NEXT_PUBLIC_BASE_URL becomes NEXT__SAFE_LOCK__PUBLIC_BASE_URL
protected_var=$(echo "$var" | sed 's/NEXT_/NEXT__SAFE_LOCK__/')
echo "Processing variable: $var -> $protected_var"
# Step 1: Protect the specific process.env reference
echo "s/process\\.env\\.$var/process.env.$protected_var/g" >> "$sed_script"
# Step 2: Replace all standalone occurrences of the variable with its value
echo "s#\\b$var\\b#$escaped_value#g" >> "$sed_script"
# Step 3: Restore the protected process.env references back to original
echo "s/process\\.env\\.$protected_var/process.env.$var/g" >> "$sed_script"
done
# Apply the sed script to all relevant files
echo "Applying replacements to .next directory..."
find ./.next -type f ! -path '*/.git/*' -exec grep -Il '.' {} \; -exec sed -i -f "$sed_script" {} +
echo "All environment variables have been processed."
echo "Starting Next.js"
echo "Running command: $@"
exec "$@"
We noticed that the .env.production file is copied to the .next/standalone/.env.production folder (with the markup values) which is copied to the application root during the build in docker, so we delete it and let next use the variables injected via configMap (k8). The problem here is that if you have a lot of variables and/or a lot of code, the application may take a while to start. |
Beta Was this translation helpful? Give feedback.
Next.js can support both build time and runtime environment variables.
By default, environments variables are only available on the server. To expose an environment variable to the browser, it must be prefixed with
NEXT_PUBLIC_
. However, these public environment variables will be inlined into the JavaScript bundle duringnext build
.To read runtime environment variables, we recommend incrementally adopting the App Router. With the App Router, we can safely read environment variables on the server during dynamic rendering. This allows you to use a singular Docker image that can be promoted through multiple environments with different values.
// This is as of Next.js 14, but you could also …