Henrique
Henrique

Reputation: 113

How can I pass an env variable to Next.JS app running inside a Docker container?

I am trying to pass the api URL as an env variable to a Next.JS app running inside a Docker container

Next.JS documentation states that: "Next.js has built-in support for loading environment variables from .env.local into process.env." and "In order to expose a variable to the browser you have to prefix the variable with NEXT_PUBLIC_."

So I created an env file called ".env.local" in the root folder of the project (same folder as the docker-compose.yaml file) with the content:

NEXT_PUBLIC_SERVER_URL=http://localhost:80

I updated the docker-compose.yaml file like this:

version: "3.8"
services:

  client:
    build: ./client
    ports:
      - "3000:3000"
    env_file:
      - .env.local

However I am unable to read the client env file in the code.

I am trying to retrieve it like Next.JS documentation suggests, I guess:

import axios from "axios";

export default axios.create({
  baseURL: `${process.env.NEXT_PUBLIC_SERVER_URL}/api/v1/`,
});

I also tried:

const serverUrl = process.env.NEXT_PUBLIC_SERVER_URL;

export default axios.create({
  baseURL: `${serverUrl}/api/v1/`,
});

It returns undefined

Upvotes: 9

Views: 20655

Answers (4)

benjick
benjick

Reputation: 149

NEXT_PUBLIC_ environment variables are replaced at build-time, but docker build does not read environment variables when building. You must use "build arguments" to pass values into the build process.

Here's an example:

FROM node:20-alpine
# ... everything else
ARG NEXT_PUBLIC_APP_URL
ENV NEXT_PUBLIC_APP_URL=$NEXT_PUBLIC_APP_URL
RUN npm run build

or with a default value:

ARG NEXT_PUBLIC_APP_URL=https://defaultvalue.example.com
ENV NEXT_PUBLIC_APP_URL=$NEXT_PUBLIC_APP_URL

Then you provide the build arguments when building your image, like this:

docker build --build-arg NEXT_PUBLIC_APP_URL=https://example.com

Upvotes: 2

sid
sid

Reputation: 2027

By default, environment variables are only available on the server. To access them on your client components, you need to expose them in your next.config.js file.

const nextConfig = {
  ...other properties,
  env: {
    PUBLIC_SERVER_URL: process.env.NEXT_PUBLIC_SERVER_URL,
  },
};

module.exports = nextConfig;

Now in your client components, you can directly access them with process.env.PUBLIC_SERVER_URL.

Upvotes: 1

Ron Newcomb
Ron Newcomb

Reputation: 3302

Alternately, you can delay those values until runtime. Somewhere in your NextJS app you probably have a <Head> component, so within there you can load late-bound values at runtime:

export default function TopOfApp() {
    // ... etc.
    return (
        <Head>
            // etc.
            <script src="./settings.js"></script>
        </Head>
    );
}

And on your deployment have the settings.js script file like

window.myAppRuntimeSettings = {
    colorOfSky: 'blue';
};

As long as you don't defer the script's loading then your app will have myAppRuntimeSettings.colorOfSky available immediately.

Upvotes: 0

Fabio Fumarola
Fabio Fumarola

Reputation: 498

Unfortunately env variables cannot be injected at runtime since the code of next.js is built into static code. The only way to solve this problem is to pass the needed variable at build time if you want to used docker.

Take a look to this discussion to understand it

Upvotes: 7

Related Questions