I am trying to containerize a frontend web application and I am having troubles to figure out how to pass environment variables. The application is a Angular application, so it is 100% client-side.
In a typical backend service, passing environment variables is easy, as everything is running on the same host, so the environment variables can be easily picked by the backend service. However, in a frontend application, this is different: the application is running in the browser of the client.
I want to configure my application via environment variables, as this makes deployment much easier. All configuration can be done in docker-compose.yml
and there is no need to maintain several images, one for every possible environment. There is just one single immutable image. This follows the 12-factor application philosophy, as can be found on https://12factor.net/config.
I am building my application image as following:
FROM node:alpine as builder
COPY package.json ./
RUN npm i && mkdir /app && cp -R ./node_modules ./app
WORKDIR /app
COPY . .
RUN $(npm bin)/ng build
FROM nginx:alpine
COPY nginx/default.conf /etc/nginx/conf.d/
RUN rm -rf /usr/share/nginx/html/*
COPY --from=builder /app/dist /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]
In app/config.ts
, I have:
export const config = {
REST_API_URL: 'http://default-url-to-my-backend-rest-api'
};
Ideally, I want to do something like this in my docker-compose.yml
:
backend:
image: ...
frontend:
image: my-frontend-app
environment:
- REST_API_URL=http://backend:8080/api
So I believe I should alter this app/config.ts
to replace REST_API_URL
with the environment variable. As I prefer an immutable Docker image (so I do not want to do this replace during the build), I am quite puzzled how to progress here. I believe I should support to alter the app/config.ts
at runtime before the nginx proxy is started. However, the fact that this file is minified and webpack-bundled, makes this more diffucult.
Any ideas how to tackle this?