VueCLI3 app (nginx/docker) use environment specific variables
I think I've accomplished to overcome this case. I am leaving the resolution here.
Define your environment-specific environment variables in
.env.development
(for development purposes) and add them also to the Pod configuration with correxponding values.Add a
configuration.js
file somewhere in your Vue project source folder. It would act as a wrapper for determining whether the runtime is development (local) or production (container). It is like the one shown here, but importing/configuringdotenv
is not required:export default class Configuration { static get EnvConfig () { return { envKey1: '$ENV_KEY_1', envKey2: '$ENV_KEY_2' } } static value (key) { // If the key does not exist in the EnvConfig object of the class, return null if (!this.EnvConfig.hasOwnProperty(key)) { console.error(`Configuration: There is no key named "${key}". Please add it in Configuration class.`) return } // Get the value const value = this.EnvConfig[key] // If the value is null, return if (!value) { console.error(`Configuration: Value for "${key}" is not defined`) return } if (!value.startsWith('$VUE_APP_')) { // value was already replaced, it seems we are in production (containerized). return value } // value was not replaced, it seems we are in development. const envName = value.substr(1) // Remove $ and get current value from process.env const envValue = process.env[envName] if (!envValue) { console.error(`Configuration: Environment variable "${envName}" is not defined`) return } return envValue }}
Create an
entrypoint.sh
. With some modification, it would look like follows:#!/bin/bashfunction join_by { local IFS="$1"; shift; echo "$*"; }# Find vue env varsvars=$(env | grep VUE_APP_ | awk -F = '{print "$"$1}')vars=$(join_by ',' $vars)echo "Found variables $vars"for file in /app/js/app.*;do echo "Processing $file ..."; # Use the existing JS file as template cp $file $file.tmpl envsubst "$vars" < $file.tmpl > $file rm $file.tmpldonenginx -g 'daemon off;'
In your
Dockerfile
, add aCMD
for running thisentrypoint.sh
script above as a bootstrapping script during container creation. So that, every time you start a container, it will get the environment variables from the pod configuration and inject it to the Configuration class shown in Step 2.# build stageFROM node:lts-alpine as build-stage# make the 'app' folder the current working directoryWORKDIR /app# Copy package*.json and install dependencies in a separaate step to enable cachingCOPY package*.json ./RUN npm install# copy project files and folders to the current working directoryCOPY ./ .# install dependencies and build app for production with minificationRUN npm run build# Production stageFROM nginx as production-stageRUN mkdir /app# copy 'dist' content from the previous stage i.e. buildCOPY --from=build-stage /app/dist /app# copy nginx configurationCOPY nginx.conf /etc/nginx/nginx.conf# Copy the bootstrapping script to inject environment-specific values and pass it as argument current to entrypointCOPY entrypoint.sh entrypoint.sh# Make the file executableRUN chmod +x ./entrypoint.shCMD ["./entrypoint.sh"]
Finally, instead of process.env
use our wrapper configuration class like Configuration.value('envKey1')
. And voila!