<p>I've been reading other questions about getting K8s environment variables to work in a Next.js app, but no accepted answer till now.</p>
<p>My app works fine using .env.local but it's getting an error (undefined) when deployed to K8s.</p>
<p>This is my next.config.js</p>
<pre class="lang-js prettyprint-override"><code>module.exports = {
  env: {
    NEXT_PUBLIC_API_BASE_URL: process.env.NEXT_PUBLIC_API_BASE_URL,
  },
};
</code></pre>
<p>K8s environment:</p>
<p><a href="https://i.stack.imgur.com/vRpyn.png" rel="noreferrer"><img src="https://i.stack.imgur.com/vRpyn.png" alt="k8s environment" /></a></p>
<p>Can anyone help me to get that environment var works on my next.js app?</p>
<p>Right now I do a simple trick, that is added ARG and ENV on dockerfile, then inject it when I build the docker image</p>
<p>Dockerfile:</p>
<pre><code>ARG NEXT_PUBLIC_API_BASE_URL
ENV NEXT_PUBLIC_API_BASE_URL=${NEXT_PUBLIC_API_BASE_URL}
</code></pre>

<p>You should add the <code>ENV_VARS</code> in a <code>.env.local</code> file. in form of a <code>configMap</code>. (<a href="https://nextjs.org/docs/basic-features/environment-variables" rel="noreferrer">https://nextjs.org/docs/basic-features/environment-variables</a>)</p>
<p>In Kubernetes you create a <code>configMap</code> like so:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
name: env-local
data:
  .env: |-
    NEXT_PUBLIC_API_URL=http:/your.domain.com/api
    API_URL=http://another.endpoint.com/serverSide
kind: ConfigMap
</code></pre>
<p>Then you mount that <code>configMap</code> as FILE into your deployment, it then is available at <code>app/.env.local</code>:</p>
<pre class="lang-yaml prettyprint-override"><code>
apiVersion: apps/v1
kind: Deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: your-app
  template:
    metadata:
      labels:
        app: your-app
    spec:
      containers:
      - image: your/image:latest
        imagePullPolicy: Always
        name: your-app
        ports:
        volumeMounts:
        - mountPath: /app/.env.local
          name: env-local
          readOnly: true
          subPath: .env.local
      volumes:
      - configMap:
          defaultMode: 420
          items:
          - key: .env
            path: .env.local
          name: env-local
        name: env-local


</code></pre>
<p>What also worked - for me at least - for <strong>server side vars</strong> was simply adding them as regular env vars in my <code>deployment</code>: <a href="https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/#define-an-environment-variable-for-a-container" rel="noreferrer">https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/#define-an-environment-variable-for-a-container</a></p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: Pod
metadata:
  name: your-app
  labels:
    purpose: demonstrate-envars
spec:
  containers:
  - name: your-app-container
    image: gcr.io/google-samples/node-hello:1.0
    env:
    - name: DEMO_GREETING
      value: &quot;Hello from the environment&quot;
    - name: DEMO_FAREWELL
      value: &quot;Such a sweet sorrow&quot;

    const withSvgr = require('next-svgr');
    
    module.exports = {   
        // Will only be available on the server side
        serverRuntimeConfig: {
            API_URL: process.env.API_URL,
        },
        // Will be available on both server and client
        publicRuntimeConfig: {
            NEXT_PUBLIC_API_URL: process.env.API_URL,
        },
    };
</code></pre>
