Como passar variáveis de ambiente para um aplicativo Web front-end?
Estou tentando containerizar um aplicativo Web front-end e estou tendo problemas para descobrir como passar variáveis de ambiente. O aplicativo é um aplicativo Angular, portanto é 100% do lado do cliente.
Em um serviço de back-end típico, é fácil passar variáveis de ambiente, pois tudo está sendo executado no mesmo host, para que as variáveis de ambiente possam ser facilmente escolhidas pelo serviço de back-end. No entanto, em um aplicativo front-end, isso é diferente: o aplicativo está sendo executado no navegador do cliente.
Quero configurar meu aplicativo por meio de variáveis de ambiente, pois isso facilita muito a implantação. Toda a configuração pode ser feita emdocker-compose.yml
e não há necessidade de manter várias imagens, uma para cada ambiente possível. Existe apenas uma única imagem imutável. Isso segue a filosofia de aplicação de 12 fatores, como pode ser encontrado emhttps://12factor.net/config.
Estou criando minha imagem de aplicativo da seguinte maneira:
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;"]
Noapp/config.ts
, Eu tenho:
export const config = {
REST_API_URL: 'http://default-url-to-my-backend-rest-api'
};
Idealmente, quero fazer algo assim no meudocker-compose.yml
:
backend:
image: ...
frontend:
image: my-frontend-app
environment:
- REST_API_URL=http://backend:8080/api
Então eu acredito que devo alterar issoapp/config.ts
substituirREST_API_URL
com a variável de ambiente. Como eu prefiro uma imagem imutável do Docker (por isso não quero fazer isso substituir durante a compilação), estou bastante confuso sobre como progredir aqui. Eu acredito que eu deveria apoiar para alterar aapp/config.ts
em tempo de execução antes do proxy nginx ser iniciado. No entanto, o fato de esse arquivo ser minificado e empacotado com o webpack torna isso mais difícil.
Alguma idéia de como lidar com isso?