Home > Mobile >  What's the best practice to expose ENV vars in a React JS app deployed on K8S?
What's the best practice to expose ENV vars in a React JS app deployed on K8S?

Time:02-15

I have a question regarding what are the best practices in managing environment variables for a React application deployed on K8S, like third-party service apiKeys from example.

Usually one could put environment variables inside the .env files, so to be picked during build phase, local or production. But we don't want to do the same while building Docker images as it would generate "hardwired" images, while the consensus/best-practice dictates that we should strictly separate code from configuration.

Containers should be agnostic to the environment in which they are to be deployed, after all.

To make thing works we wrote a docker-entrypoint.sh script where we take variables from the environment the container is run into, and we write those variables values into the window object, so that React runtime can access them.

To be more clear, this is the content of our docker-entrypoint.sh:

if [ -v VARIABLE_NAME ]; then
    variable_name="window.VARIABLE_NAME = '${VARIABLE_NAME}';"
fi

echo "${variable_name}" > /usr/share/nginx/html/static/app-config.js

exec "$@"

And in the <head> section of our React's index.html we have this:

<script src="%PUBLIC_URL%/static/app-config.js"></script>

So all the variables are accessible via window.VARIABLE_NAME.

In our case we're taking env variables exposed into Pod by Kubernetes.
Our solution works, but we need to understand if there are better approaches.

These are useful links we followed:
https://12factor.net/config
https://docs.docker.com/engine/faq/#what-does-docker-technology-add-to-just-plain-lxc

CodePudding user response:

you can store the key:value pairs of your ENVs in kubernetes secrets and expose them to your service as ENVs by referencing the secret(s) in your deployment.

secret.yaml:

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  env1: value1
  env2: value2

deployment.yaml:

kind: Deployment
apiVersion: apps/v1
metadata:
  ...
spec:
  ...
  template:
    ...
    spec:
      ...
      containers:
        - name: <app>
          image: <image>
          env:
            - name: env1
              valueFrom:
                secretKeyRef:
                  name: mysecret
                  key: env1
            - name: env2
              valueFrom:
                secretKeyRef:
                  name: mysecret
                  key: env2
          ...

reference: https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables

CodePudding user response:

ConfigMap is what you are looking for to achieve it.

A ConfigMap is an API object used to store non-confidential data in key-value pairs. Pods can consume ConfigMaps as environment variables, command-line arguments, or as configuration files in a volume. A ConfigMap allows you to decouple environment-specific configuration from your container images, so that your applications are easily portable.

In short way ConfigMap takes variables from file and attach them to Pod.

You can get familiar in more details in another my answer. I wrote step by step with explanation in each step.

If you have sensitive data you can read about Secrets

A Secret is an object that contains a small amount of sensitive data such as a password, a token, or a key. Such information might otherwise be put in a Pod specification or in a container image Using a Secret means that you don't need to include confidential data in your application code.

  • Related