Buildtime vs runtime environment variables with Next.js and Docker
For a Next.js app, buildtime environment variables are variables that are used when the next build
command runs. Runtime variables are variables used when the next start
command runs.
Below are ways to set buildtime and rutime environment variables with Docker and ways to use buildtime and runtime environment variables with Next.js. Note the Dockerfile
is written for simplicity to illustrate the examples. For a more optimized Next.js Docker build see my Docker multi-stage CI example.
Methods for setting environment variables with Docker ¶
Method | Available at buildtime | Available at runtime | Value passed to docker build | Value passed to docker run |
---|---|---|---|---|
ARG | ✔ | |||
ENV | ✔ | ✔ | ||
ARG + docker build --build-arg | ✔ | ✔ | ||
ARG + ENV + docker build --build-arg | ✔ | ✔ | ✔ | |
docker run --env | ✔ | ✔ |
Methods for using environment variables in Next.js ¶
Method | Set at | Available in Next.js client side rendered code (browser) | Available in Next.js server side rendered code | Available in Node.js | Notes |
---|---|---|---|---|---|
.env files | ?both? | ✔ | process.env cannot be destructured or accessed with dynamic properties | ||
NEXT_PUBLIC_ prefixed vars in .env files | buildtime | ✔ | ✔ | process.env cannot be destructured or accessed with dynamic properties | |
env in next.config.js | buildtime | ✔ | ✔ | process.env cannot be destructured or accessed with dynamic properties | |
publicRuntimeConfig | runtime | ✔ | ✔ | Requires page uses SSR | |
serverRuntimeConfig | runtime | ✔ | |||
process.env | runtime | ✔ |
Assume this package.json
for the examples below ¶
{
"scripts": {
"build": "next build",
"dev": "next",
"start": "next start"
},
"dependencies": {
"next": "^10.0.9",
"react": "^17.0.2",
"react-dom": "^17.0.2"
}
}
Setting static environment variables for buildtime and runtime ¶
Environment variables can be specified with the ENV
instruction in a Dockerfile
. Below MY_VAR
will be available to both next build
and next start
. For more information see https://docs.docker.com/engine/reference/builder/#env
Dockerfile
FROM node:14-alpine
ENV MY_VAR=cake
WORKDIR /app
COPY . ./
RUN npm install
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
Docker build
docker build -t mytag .
Docker run
docker run mytag
Setting dynamic buildtime environment variables ¶
Dynamic environment variables can be passed to the docker build
command using --build-arg
and used in the Dockerfile
with the ARG
statement. Below MY_VAR
is an environment variable available to next build
.
Note that MY_VAR
is not available to next start
. ARG
statements act like ENV
statements in that they are treated like environment variables during docker build
, but they are not persisted in the image. To make them available during docker run
(and next start
) set the value using ENV
(see the next example).
For more information see https://docs.docker.com/engine/reference/builder/#arg
Dockerfile
FROM node:14-alpine
ARG MY_VAR
WORKDIR /app
COPY . ./
RUN npm install
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
Docker build
docker build --build-arg MY_VAR=cake -t mytag .
Docker run
docker run mytag
Setting dynamic buildtime environment variables that are available at runtime also ¶
The variable in the previous example, set using ARG
, is not persisted in the Docker image so it is not available at runtime. To make it available at runtime, copy the value from ARG
to ENV
.
Dockerfile
FROM node:14-alpine
ARG MY_VAR
ENV MY_VAR=$MYVAR
WORKDIR /app
COPY . ./
RUN npm install
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
Docker build
docker build --build-arg MY_VAR=cake -t mytag .
Docker run
docker run mytag
Setting dynamic runtime environment variables ¶
Dynamic environment variables can be passed to docker run
using the --env
flag. These will not be available to next build
but they will be available to next start
. For more information see https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file
Dockerfile
FROM node:14-alpine
WORKDIR /app
COPY . ./
RUN npm install
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
Docker build
docker build -t mytag .
Docker run
docker run --env MY_VAR=cake mytag
Using buildtime environment variables ¶
To use buildtime environment variables in Next.js code, set them using env
in next.config.js
. Then access them via process.env
in your app code. NOTE: process.env
cannot be destructured or used with dynamic property access. Next.js does a string substituion at build time using the webpack DefinePlugin. For more information see https://nextjs.org/docs/api-reference/next.config.js/environment-variables
next.config.js
module.exports = {
env: {
MY_VAR: process.env.MY_VAR
}
}
my-app-file.js
console.log(process.env.MY_VAR)
Using runtime environment variables (client-side or server-side) ¶
To use runtime environment variables (client-side or server-side), set them using publicRuntimeConfig
in next.config.js
. Then access them using getConfig
from next/config
. NOTE: this only works for Next.js pages where server-side rendering (SSR) is used. i.e. the page must use getServerSideProps
or getInitialProps
. For more information see https://nextjs.org/docs/api-reference/next.config.js/runtime-configuration
next.config.js
module.exports = {
publicRuntimeConfig: {
MY_VAR: process.env.MY_VAR
}
}
my-app-file.js
import getConfig from "next/config";
const { publicRuntimeConfig } = getConfig();
console.log(publicRuntimeConfig.MY_VAR)
Using runtime environment variables (server-side only) ¶
To use runtime environment variables (server-side only), set them using serverRuntimeConfig
in next.config.js
. Then access them using getConfig
from next/config
. For more information see https://nextjs.org/docs/api-reference/next.config.js/runtime-configuration
NOTE: this applies to to files Next.js "builds". Server run files not processed by Next.js can use process.env
to access environment variables. See below.
next.config.js
module.exports = {
serverRuntimeConfig: {
MY_VAR: process.env.MY_VAR
}
}
my-app-file.js
import getConfig from "next/config";
const { serverRuntimeConfig } = getConfig();
console.log(serverRuntimeConfig.MY_VAR)
Using runtime environment variables server-side (not processed by Next.js) ¶
For files not processed by Next.js (next build
) (e.g. a server.js
file run by node
), runtime environment variables can be accessed on the server via process.env
. NOTE: "runtime" variables here means variables used when the Node.js process runs. For more information see https://nodejs.org/docs/latest-v14.x/api/process.html#process_process_env
server.js
console.log(process.env.MY_VAR)
Next.js assetPrefix
¶
If the Next.js assetPrefix
is set in next.config.js
using an environment variable, the environment variable should be set at buildtime for Next.js static pages but set at runtime for server rendered pages.
next.config.js
module.exports = {
assetPrefix: process.env.MY_ASSET_PREFIX
}
Related posts
- How to use ast-grep with GraphQL — posted 2024-09-24
- Next.js App Router (RSC) projects w/ open source code — posted 2024-07-30
- Next.js Relay GraphQL Pokemon example — posted 2024-05-22
- Example Node.js Passport.js SAML app using OneLogin — posted 2024-05-10
- Aphrodite to CSS Modules codemod — posted 2022-12-09
- Simple codemod example with jscodeshift — posted 2021-05-03