How to load the configurations from .env during the app startup?

1.1k Views Asked by At

I have a quasar app that uses DOTENV - Quasar Framework app extension to load configurations from file .env.

When the quasar app gets build, then it will load all the configurations from .env file but I want to load the .env file when the app get started.

The app runs on Kubernetes and all the configurations are stored asConfigMap. During the container startup, I mount the .env file as the following:

      containers:
        - name: argo-ui-test
          image: "example.io/ui/argo-ui-test:0.1.9"
          volumeMounts:
          - name: svc-config-url
            mountPath: /app/.env
            subPath: .env
          imagePullPolicy: Always
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            {}
      volumes:
        - name: svc-config-url
          configMap:
            name: svc-url

When I look inside the container, the file has been successfully mounted:

drwxr-xr-x 1 root root  4096 Oct 17 10:33 .
drwxr-xr-x 1 root root  4096 Oct 17 10:33 ..
-rw-r--r-- 1 root root    97 Oct 17 10:33 .env
-rw-r--r-- 1 root root   494 Oct  6 09:12 50x.html
drwxr-xr-x 2 root root  4096 Oct 17 09:33 css
-rw-r--r-- 1 root root 16645 Oct 17 09:33 favicon.ico
drwxr-xr-x 2 root root  4096 Oct 17 09:33 fonts
drwxr-xr-x 2 root root  4096 Oct 17 09:33 icons
-rw-r--r-- 1 root root   905 Oct 17 09:33 index.html
drwxr-xr-x 2 root root  4096 Oct 17 09:33 js
I have no name!@argo-ui-test-5c65cb78dc-jnshk:/app$ cat .env
KC_SVC_URL=https://oic.dev.example.io/auth/
USER_SVC_URL=https://user.dev.svc.example.io/api/

The quasar app does not load the configurations from .env file when it starts. What am I doing wrong?

1

There are 1 best solutions below

0
On

The environment variables actually get referenced and baked into the built artifacts at build time (npm build stage), not run time.

If you want to change them at run time. you have to do a little more work. one method that works with me is providing a custom entry point shell script (in your docker file for example):

CMD ["sh", "/entrypoint.sh"]

And the shell script would have:

#!/bin/sh

# Replace env vars in JavaScript files
echo "Replacing env vars in JS"
for file in app/js/app.*.js;
do
  echo "Processing $file ...";

  # Use the existing JS file as template
  if [ ! -f $file.tmpl.js ]; then
    cp $file $file.tmpl.js
  fi

  envsubst '$VUE_APP_BACKEND_HOST' < $file.tmpl.js > $file
done

echo "Starting Nginx"
nginx -g 'daemon off;'

This will change any instances of $VUE_APP_BACKEND_HOST from the built code with the current environment variable passed to the kube pod/docker run, this shell actually starts an nginx to serve the files, but you can change it to anything you want

I also use this script as a helper in the App to reference all vars from one place, i only use .env files during development, when deploying i use config maps to map these values directly to env vars.

export default class Configuration {
  static get CONFIG () {
    return {
      backendHost: '$VUE_APP_BACKEND_HOST',
    }
  }

  static value (name) {
    if (!(name in this.CONFIG)) {
      console.log(`Configuration: There is no key named "${name}"`)
      return
    }

    const value = this.CONFIG[name]

    if (!value) {
      console.log(`Configuration: Value for "${name}" is not defined`)
      return
    }

    if (value.startsWith('$VUE_APP_')) {
      // value was not replaced, it seems we are in development.
      // Remove $ and get current value from process.env
      const envName = value.substr(1)
      const envValue = process.env[envName]
      if (envValue) {
        return envValue
      } else {
        console.log(`Configuration: Environment variable "${envName}" is not defined`)
      }
    } else {
      // value was already replaced, it seems we are in production.
      return value
    }
  }
}