Azure App Services - Multi-Container Apps - NGINX + Reverse Proxy
Olá PessoALL,
No post anterior eu dei uma pequena introdução sobre como funcionar o App Service com containers.
Hoje vamos falar sobre como rodar múltiplos containers em um único App Service, para isso pretendo simular um cenário com múltiplas apis expostas como um único serviço:
- NGINX atuando como proxy reverso e redirecionando minhas chamadas de api para os containers correspondentes.
- ORDERS é o container que lida com as ordens do meu sistema e será acessado pela url /orders/
- PAYMENTS é o container que lida com os pagamentos do meu sistema e será acessado pela url /payments/
As Imagens
No meu repositório tenho duas apis bem simples para responderem as requisições com mensagens pré-definidas, só para ilustrar o processo de configuração do proxy reverso.
Uma das limitações do App Service atualmente é que todas as imagens utilizadas no docker compose precisam estar no mesmo registro, sendo assim além das imagens das minhas apis eu criei uma imagem com o mesmo conteúdo da imagem do NGINX oficial e subi no meu registro.
FROM nginx:latest
# NOTE: For now we do nothing, we just need to have the nginx image on the same registry as our
# private containers
#COPY nginx.conf /etc/nginx/nginx.conf
Não é o objetivo desse post ensinar como fazer o build das imagens e o push para o registro, mas se deseja aprender como funciona deixa um comentário aqui no post que talvez eu escreva um post (ou grave um vídeo) ensinando como é a dinâmica.
Ao final tenho as seguintes imagens:
- rsantosdev.azurecr.io/rsantosdev/aspnetcore-nginx
- rsantosdev.azurecr.io/rsantosdev/aspnetcore-nginx-orders
- rsantosdev.azurecr.io/rsantosdev/aspnetcore-nginx-payments
Observe que rsantosdev.azurecr.io é o prefixo do meu registro de imagens no Azure.
Docker Compose
Na aba de configuração do seu container, atualize seu arquivo conforme a seguinte configuração:
version: "3"
services:
nginx:
image: rsantosdev.azurecr.io/rsantosdev/aspnetcore-nginx
restart: always
container_name: dev_nginx
volumes:
- ${WEBAPP_STORAGE_HOME}/site/wwwroot/nginx.az.conf:/etc/nginx/nginx.conf
- ${WEBAPP_STORAGE_HOME}/site/wwwroot:/var/www/html
ports:
- "80:80"
orders:
image: rsantosdev.azurecr.io/rsantosdev/aspnetcore-nginx-orders
container_name: dev_orders
restart: always
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://+:8080
payments:
image: rsantosdev.azurecr.io/rsantosdev/aspnetcore-nginx-payments
container_name: dev_payments
restart: always
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://+:8080
Precisamos atualizar nosso nginx.az.conf para atuar como proxy reverso, conforme a configuração a seguir:
worker_processes 1;
events { worker_connections 1024; }
http {
log_format compression '$remote_addr - $remote_user [$time_local] '
'"$request" $status $upstream_addr '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
server {
listen 80;
server_name _;
root /var/www/html;
access_log /var/log/nginx/access.log compression;
index hostingstart.html index.html;
location /orders/ {
proxy_pass http://orders:8080/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
location /payments/ {
proxy_pass http://payments:8080/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
}
A configuração por parecer um pouco complexa, mas não é. No nosso arquivo docker compose configuramos nossos containers para rodarem na porta 8080 e no arquivo de configuração do nginx repassamos as requisições para os respectivos containers nessa mesma porta.
Checou a hora de testarmos se tudo está funcionando:



Pronto! Temos nosso App Service com um proxy reverso e duas apis que são "servidas" no mesmo endereço. Antes de terminar queria salientar que fiz isso para estudos e em cenários pequenos a configuração atende bem, mas para sistemas complexos e produção pode ser complicado usar a técnica, pois qualquer alteração nos containers ou na configuração do proxy precisariamos mudar os arquivos.
Avalie bem, pois existem inúmeros serviços especializados inclusive open-source que podem ser usados.
Por hoje é só! No próximo post pretendo demonstrar como trabalhar com webjobs usando containers.
Não deixe de comentar o que achou do post ou deixar sua sugestão.
[]s e até a próxima.