Reputation: 113
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
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
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
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
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