How can I access environment variables in Vue, that are passed to the container at runtime and not during the build?
Stack is as follows:
I am adding my working solution here, for those who are still having trouble. I do think that @Hendrik M Halkow 's answer is more elegant, though I couldn't manage to solve it using that, simply just because of my lack of expertise in webpack and Vue.I just couldn't figure out where to put the config file and how to refer it.
My approach is to make use of the environment variables with constants (dummy values) to build it for production
, then replace that constants in the image using a custom entrypoint
script. The solution goes like this.
I have encapsulated all configs into one file called app.config.js
export const clientId = process.env.VUE_APP_CLIENT_ID
export const baseURL = process.env.VUE_APP_API_BASE_URL
export default {
clientId,
baseURL,
}
This is used in the project just by looking up the value from config file.
import { baseURL } from '@/app.config';
Then I am using standard .env.[profile] files to set environment variables.
e.g. the .env.development
VUE_APP_API_BASE_URL=http://localhost:8085/radar-upload
VUE_APP_CLIENT_ID=test-client
Then for production I set string constants as values.
e.g. the .env.production
VUE_APP_API_BASE_URL=VUE_APP_API_BASE_URL
VUE_APP_CLIENT_ID=VUE_APP_CLIENT_ID
Please not here the value can be any unique string. Just to keep the readability easier, I am just replacing the environment variable name as the value. This will just get compiled and bundled similar to development mode.
In my Dockerfile
, I add an entrypoint
that can read those constants and replace it will environment variable values.
My Dockerfile looks like this (this is pretty standard)
FROM node:10.16.3-alpine as builder
RUN mkdir /app
WORKDIR /app
COPY package*.json /app/
RUN npm install
COPY . /app/
RUN npm run build --prod
FROM nginx:1.17.3-alpine
# add init script
COPY ./docker/nginx.conf /etc/nginx/nginx.conf
WORKDIR /usr/share/nginx/html
COPY --from=builder /app/dist/ .
COPY ./docker/entrypoint.sh /entrypoint.sh
# expose internal port:80 and run init.sh
EXPOSE 80
ENTRYPOINT ["/entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]
Then create a ./docker/entrypoint.sh file as below.
#!/bin/sh
ROOT_DIR=/usr/share/nginx/html
# Replace env vars in JavaScript files
echo "Replacing env constants in JS"
for file in $ROOT_DIR/js/app.*.js* $ROOT_DIR/index.html $ROOT_DIR/precache-manifest*.js;
do
echo "Processing $file ...";
sed -i 's|VUE_APP_API_BASE_URL|'${VUE_APP_API_BASE_URL}'|g' $file
sed -i 's|VUE_APP_CLIENT_ID|'${VUE_APP_CLIENT_ID}'|g' $file
done
echo "Starting Nginx"
nginx -g 'daemon off;'
This enables me to have runtime configurable image that I can run on many environments. I know it is a bit of a hack. But have seen many people do it this way.
Hope this helps someone.