Home > OS >  Pass (Docker) environment variable into Vue/Quasar application at runtime
Pass (Docker) environment variable into Vue/Quasar application at runtime

Time:05-09

Having read the Quasar framework's description for Handling process.env, I understand that it is possible to add environment variables when building the application for development or production.

You can even go one step further. Supply it with values taken from the quasar dev/build env variables:

// quasar.config.js
build: {
  env: {
    FOO: process.env.FOO,
  }
}

Then, I can use that variable by using process.env.FOO.

For staging and production, however, I'm building a Docker image which runs an NGINX serving the final dist/spa folder. I'd like to pass an environment variable when deploying the application, so that I can configure the FOO variable depending on its value in the docker-compose.yml:

// staging
services:
  image: my-quasar-image
  environment:
    FOO: "STAGING"

// production
services:
  image: my-quasar-image
  environment:
    FOO: "PROD"

I have found some blog post which mentions that you could create a custom entrypoint.sh for the Docker image which reads env variables and adds them to the window object but I wonder if there might be a more "elegant" solution.

The primary question is: Is it possible to pass in (Docker) environment variables before the application starts and which are then available on process.env?

CodePudding user response:

This is how I sorted my requirement that works perfectly for my use case. A quick review of what I wanted to do: Be able to pass in environment variables via a docker-compose file to a Vue.js application to allow different team members to test different development APIs depending on their assignment(localhost if running the server locally, api-dev, api-staging, api-prod).

Update public/index.html to contain following at the head:

<script>
   // CONFIGURATIONS_PLACEHOLDER
</script>

There is no need to update vue.config.js as we are using the public folder for configuration.

Create new file env.js to consume runtime variables (keep it inside src folder)

export default function getEnv(name) {
    return window?.configs?.[name] || process.env[name];
}

Create new bash file set-env-variable.sh in the root folder of the app.

#!/bin/sh
JSON_STRING='window.configs = { \
  "VUE_APP_VAR1":"'"${VUE_APP_VAR1}"'", \
  "VUE_APP_VAR2":"'"${VUE_APP_VAR2}"'" \
}'
sed -i "s@// CONFIGURATIONS_PLACEHOLDER@${JSON_STRING}@" /usr/share/nginx/html/index.html
exec "$@"

Update docker file (assuming it's in the root folder of your vue app)

# build stage
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html

COPY ./set-env-variable.sh /docker-entrypoint.d
RUN chmod  x /docker-entrypoint.d/set-env-variable.sh
RUN dos2unix /docker-entrypoint.d/set-env-variable.sh

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Deployment

vue-app:
    ....
    volumes:
      - "./nginx/templates/:/etc/nginx/templates/"
    environment:
      VUE_APP_VAR1: my-app
      VUE_APP_VAR2: 8080

Consuming variables in vue app

import getEnv from "./service/env.js";
var myVar = getEnv("VUE_APP_VAR1");
  • Related