#Can't access env variables in kubernetes (React Vite)

1 messages · Page 1 of 1 (latest)

trim vortex
#

I'm trying to access environment variables, but it just won't work for some reason. I also can't find anything on the internet about this. The variables do exist inside kubernetes, but Vite can't seem to access them for some reason, because they're always logged as undefined.

.env

VITE_AUTH0_DOMAIN=bzbz
VITE_AUTH0_CLIENT_ID=bzbz
VITE_AUTH0_AUDIENCE=bzbz

I've tried acccessing them like:

const domain = process.env.VITE_AUTH0_DOMAIN || '';
const clientId = process.env.VITE_AUTH0_CLIENT_ID || '';

but also like:

const domain = import.meta.env.VITE_AUTH0_DOMAIN;
const clientId = import.meta.env.VITE_AUTH0_CLIENT_ID;

In Docker it all works fine, but in Kubernetes it won't, I'm curious as to what's different. I tried different vite.config.ts setups too, this is the most recent one:

import path from "path"
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import ImportMetaEnvPlugin from "@import-meta-env/unplugin";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react(), ImportMetaEnvPlugin.vite({
      example: ".env.example",
      env: ".env"
    }),
  ],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
  server: {
    port: 3000,
  },
  preview: {
    port: 3000
  },
  define: {
    'process.env.VITE_AUTH0_DOMAIN': JSON.stringify(process.env.VITE_AUTH0_DOMAIN),
    'process.env.VITE_AUTH0_CLIENT_ID': JSON.stringify(process.env.VITE_AUTH0_CLIENT_ID),
    'process.env.VITE_AUTH0_AUDIENCE': JSON.stringify(process.env.VITE_AUTH0_AUDIENCE),
  }
})

Anyone any idea what's happening?

gilded cave
#

Interesting. The define configuration should be pretty foolproof. It's building the environment variables into your package. So, if they're not there even with define, then I think something must be removing them at runtime? I see you also have the @import-meta-env/unplugin package configured. Is that maybe "helping" by removing any environment variables it doesn't own at runtime? What happens if you have only the define?

#

Also, in docker and k8s, are you using the same container image in both?

trim vortex
#

Also, in docker and k8s, are you using the same container image in both?
yessir, k8s file pulls the image from Dockerhub

Maybe I'm understanding it wrong, but after running: kubectl exec -it frontend-6ddb87dd49-ggl5z -- env to display the pod's env variables it does show the ones I add in the deployment file.

gilded cave
#

env wouldn't know about code inside your bundle (define), and I don't "think" it would know about the .env file either.

trim vortex
#

I removed the ImportMetaEnvPlugin btw and only left define, but still doesn't work

gilded cave
#

The command you have above is basically running the env command inside a container. That would know about environment variables assigned by k8s, or maybe defined in a shell startup script, but not constants inside your bundle or .env files that have no special meaning to k8s/os/shell.

#

When you say it doesn't work, are you basing it on the env command, or on something the bundle is not doing that it should be doing?

trim vortex
#

I add the env vars in k8s in the deployment file like:

env:
  - name: VITE_AUTH0_DOMAIN
    value: bzbzb
  - name: VITE_AUTH0_CLIENT_ID
    value: bzbzbz
  - name: VITE_AUTH0_AUDIENCE
    value: bzbz
trim vortex
#

Like a month ago I did another test in which I simply log the value and it would log undefined

gilded cave
#

I wouldn't expect the Vite bundle to use environment variables from your container... Vite "environment" variables are compiled into the bundle as constants, because the bundle runs on the client (browser) without access to the server environment or file system.

trim vortex
#

this is such an interesting issue because you'd think alot of people use it and have run into this, but what I can find online is very limited

gilded cave
#

Vite + Auth0 + K8s. Yes, you would think that would be reasonably common. But each person's config/environment is pretty unique.

#

So, I would redo your logging test to see if define is working in k8s. Because that definitely should be.

coarse cloak
#

import.meta.env.VITE_... should be the way to access the vars inside the javascript code i think

#

can you show your dockerfile?

#

and possibly k8s manifests etc

trim vortex
# coarse cloak and possibly k8s manifests etc

Dockerfile:

FROM node:21-alpine AS build

WORKDIR /app

COPY package.json .

RUN npm install

COPY . .

RUN npm run build

# Use Nginx as the production server
FROM nginx:alpine
COPY ./.nginx/nginx.conf /etc/nginx/nginx.conf

# Copy the built React app to Nginx's web server directory
COPY --from=build /app/dist /usr/share/nginx/html

# Expose port 80 for the Nginx server
EXPOSE 3000

# Start Nginx when the container runs
CMD ["nginx", "-g", "daemon off;"]

Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    kompose.cmd: C:\Windows\system32\kompose.exe convert
    kompose.version: 1.26.0 (40646f47)
  creationTimestamp: null
  labels:
    io.kompose.service: frontend
  name: frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      io.kompose.service: frontend
  strategy: {}
  template:
    metadata:
      annotations:
        kompose.cmd: C:\Windows\system32\kompose.exe convert
        kompose.version: 1.26.0 (40646f47)
      creationTimestamp: null
      labels:
        io.kompose.network/backend: "true"
        io.kompose.service: frontend
    spec:
      containers:
        - image: [Image]
          name: frontend
          ports:
            - containerPort: 3000
          resources: {}
      restartPolicy: Always
status: {}

Service:

apiVersion: v1
kind: Service
metadata:
  annotations:
    kompose.cmd: C:\Windows\system32\kompose.exe convert
    kompose.version: 1.26.0 (40646f47)
  creationTimestamp: null
  labels:
    io.kompose.service: frontend
  name: frontend
spec:
  type: LoadBalancer
  ports:
    - name: "3000"
      port: 3000
      targetPort: 3000
  selector:
    io.kompose.service: frontend
status:
  loadBalancer: {}
coarse cloak
#

in your dockerfile, you copy package.json into the /app dir, install node modules and then copy the rest of the source files. does that copy the .env file as well? you mentioned that it works in docker(locally) but not on k8s. either way, check if the .env file is indeed copied over.

plucky verge
coarse cloak
#

at work, we dont use .env file in production, since it is considered bad practise to store it in the git repo. but it doesnt mean you cannot do it. my best bet here is that docker ignores the .env file as a hidden file and the destination folder ends up without an .env file. try manually copying it, COPY .env /app/

coarse cloak
#

did that work?

trim vortex
#

I've been busy last days, so I'll be checking it out tomorrow 🙌

coarse cloak
#

ok

trim vortex
# coarse cloak did that work?

Yes it did, I just commited the .env and added the COPY statement. Since the env values in the frontend are public anyway there's no reason to create secrets for them.