Estou pensando em como isso deve ser feito de maneira séria há semanas e ainda não cheguei a uma conclusão. Talvez eu pense na direção errada.
Digamos que você tenha uma centena de aplicativos da web que vêm e vão. Você quer uma configuração nginx como essa com o exemplo do gitlab:
location / {
proxy_pass http://gitlab;
}
Como o gitlab foi criado com docker service create
, o nginx poderá resolver o gitlab por seu nome de DNS falso swarm-vip dentro de sua rede de ingresso.
MAS: somente se o contêiner de serviço estiver em execução. Caso contrário, o nginx não iniciará devido a [emerg] 1#1: host not found in upstream "gitlab"
Agora, isso é um quebra-galhos quando você precisa executar um nginx de alta disponibilidade e não é da sua conta garantir que os aplicativos proxy_pass'ed estejam em execução.
Toda vez que você atualizar o serviço nginx, ele não será exibido se apenas um dos cem outros serviços de enxame não estiver em execução nem pelo mesmo segundo .. wtf?
Se isso não está funcionando, por que no mundo precisamos de resolução de nomes em enxame? Como você resolve este problema?
Eu pensei em cônsul e geração dinâmica de modelos de host virtual nginx (nem pense em docker-nginx-proxy!), mas os aplicativos são muito diferentes que você pode dizer que cada aplicativo tem sua própria configuração individual. E tudo isso funciona não por um motivo especial, apenas para resolver o problema de resolução do nginx?
Eu recomendaria trocar o proxy reverso nginx definido estaticamente por traefik, que reconhece enxame e pode se reconfigurar dinamicamente à medida que os serviços são implantados e destruídos.
Aqui está um exemplo de implementação:
crie uma rede para o traefik falar com os containers:
docker network create proxy
Faça um traefik.toml, aqui está um exemplo:
traefik.toml
docker-compose.traefik.yml
docker-compose.app.yml
A regra acima usa prefixos de caminho para o contêiner para simplificar, mas você pode usar qualquer regra de sua preferência para fazer proxy de seu aplicativo.