Next.js Environment variables work locally but not when hosted on Kubernetes

11/26/2019

Have a Next.js project.

This is my next.config.js file, which I followed through with on this guide: https://dev.to/tesh254/environment-variables-from-env-file-in-nextjs-570b

module.exports = withCSS(withSass({
    webpack: (config) => {
        config.plugins = config.plugins || []
        config.module.rules.push({
          test: /\.svg$/,
          use: ['@svgr/webpack',  {
            loader: 'url-loader',
            options: {
                limit: 100000,
                name: '[name].[ext]'
            }}],
        });

        config.plugins = [
          ...config.plugins,

          // Read the .env file
          new Dotenv({
            path: path.join(__dirname, '.env'),
            systemvars: true
          })
        ]

        const env = Object.keys(process.env).reduce((acc, curr) => {
          acc[`process.env.${curr}`] = JSON.stringify(process.env[curr]);
          return acc;
        }, {});
        // Fixes npm packages that depend on `fs` module
        config.node = {
          fs: 'empty'
        }

         /** Allows you to create global constants which can be configured
        * at compile time, which in our case is our environment variables
        */
        config.plugins.push(new webpack.DefinePlugin(env));

        return config
      }
    }),

    );

I have a .env file which holds the values I need. It works when run on localhost.

In my Kubernetes environment, within the deploy file which I can modify, I have the same environment variables set up. But when I try and identify them they come off as undefined, so my application cannot run.

I refer to it like:

process.env.SOME_VARIABLE

which works locally.

Does anyone have experience making environment variables function on Next.js when deployed? Not as simple as it is for a backend service. :(

EDIT: This is what the environment variable section looks like.

EDIT 2: Full deploy file, edited to remove some details

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "38"
  creationTimestamp: xx
  generation: 40
  labels:
    app: appname
  name: appname
  namespace: development
  resourceVersion: xx
  selfLink: /apis/extensions/v1beta1/namespaces/development/deployments/appname
  uid: xxx
spec:
  progressDeadlineSeconds: xx
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: appname
      tier: sometier
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: appname
        tier: sometier
    spec:
      containers:
      - env:
        - name: NODE_ENV
          value: development
        - name: PORT
          value: "3000"
        - name: SOME_VAR
          value: xxx
        - name: SOME_VAR
          value: xxxx
        image: someimage
        imagePullPolicy: Always
        name: appname
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
            port: 3000
            scheme: HTTP
          initialDelaySeconds: 5
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 1
  conditions:
  - lastTransitionTime: xxx
    lastUpdateTime: xxxx
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  observedGeneration: 40
  readyReplicas: 1
  replicas: 1
  updatedReplicas: 1
-- BURGERFLIPPER101
environment-variables
kubernetes
next.js

1 Answer

11/26/2019

.env Works in docker or docker-compose, they do not work in Kubernetes, if you want to add them you can by configmaps objects or add directly to each deployment an example (from documentation):

apiVersion: v1
kind: Pod
metadata:
  name: envar-demo
  labels:
    purpose: demonstrate-envars
spec:
  containers:
  - name: envar-demo-container
    image: gcr.io/google-samples/node-hello:1.0
    env:
    - name: DEMO_GREETING
      value: "Hello from the environment"
    - name: DEMO_FAREWELL
      value: "Such a sweet sorrow

Also, the best and standard way is to use config maps, for example:

  containers:
    - env:
        - name: DB_DEFAULT_DATABASE
          valueFrom:
            configMapKeyRef:
              key: DB_DEFAULT_DATABASE
              name: darwined-env

And the config map:

apiVersion: v1
data:
  DB_DEFAULT_DATABASE: darwined_darwin_dev_1
 kind: ConfigMap
metadata:
  creationTimestamp: null
  labels:
    io.kompose.service: darwin-env
  name: darwined-env

Hope this helps.

-- paltaa
Source: StackOverflow