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:

Requisição servindo nosso "index.html"
Serviço de Ordens
Serviço de pagamentos

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.