Atribuindo vhosts a portas do Docker

Eu tenho um DNS curinga configurado para que todas as solicitações da Web para um domínio personalizado (* .foo) mapeiam para o endereço IP do host do Docker. Se eu tiver vários contêineres executando instâncias do Apache (ou Nginx), cada contêiner mapeará a porta do Apache (80) para alguma porta de input externa.

O que eu gostaria de fazer é fazer uma solicitação para o container 1-.foo, que já está mapeado para o endereço IP correto (do host do Docker) através do meu servidor DNS personalizado, mas proxy da porta padrão 80 para o Docker externo correto porta de modo que a instância correta do Apache do contêiner especificado seja capaz de responder com base no domínio personalizado. Da mesma forma, container-2.foo seria um proxy para o apache de um segundo contêiner e assim por diante.

Existe uma solução pré-construída para isso, é a minha melhor aposta para executar um proxy Nginx no host do Docker ou devo escrever um proxy node.js com potencial para gerenciar contêineres do Docker (iniciar / parar / reconstruir pela Web ), ou …? Quais opções eu tenho que fariam usando os contêineres Docker mais como um evento natural e não algo com portas estranhas e malabarismo de contêineres?

Esta resposta pode ser um pouco tarde, mas dê uma olhada na imagem nginx-proxy Docker de Jason Wilder . Ao executar um contêiner do Docker dessa imagem, você obtém um servidor nginx configurado como um proxy reverso para seus outros contêineres sem configuração para manter.

Apenas execute seus outros contêineres com a variável de ambiente VIRTUAL_HOST e o nginx-proxy descobrirá seu ip: port e atualizará a configuração do nginx para você.

Digamos que seu DNS esteja configurado para que o *.test.local mapeie para o endereço IP do seu host do Docker e, em seguida, inicie os contêineres a seguir para obter uma demonstração rápida em execução:

 # start the reverse proxy docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy # start a first container for http://tutum.test.local docker run -d -e "VIRTUAL_HOST=tutum.test.local" tutum/hello-world # start a second container for http://deis.test.local docker run -d -e "VIRTUAL_HOST=deis.test.local" deis/helloworld 

Aqui estão duas respostas possíveis: (1) configurar portas diretamente com o Docker e usar o Nginx / Apache para fazer proxy dos vhosts ou (2) usar o Dokku para gerenciar portas e vhosts para você (que foi como aprendi a fazer o Método 1).

Método 1a (atribuir diretamente as portas com a janela de encaixe)

Etapa 1: configure o nginx.conf ou o Apache no host, com as atribuições de número de porta desejadas. Este servidor web, rodando no host, fará o proxy vhost. Não há nada de especial nisso em relação ao Docker – é uma hospedagem vhost normal. A parte especial vem em seguida, na Etapa 2, para fazer o Docker usar o número correto da porta do host.

Etapa 2: forçar as atribuições de número de porta no Docker com “-p” para definir os mapeamentos de porta do Docker e “-e” para definir variables ​​de ambiente personalizadas no Docker, da seguinte maneira:

 port=12345 # <-- the vhost port setting used in nginx/apache IMAGE=myapps/container-1 id=$(docker run -d -p :$port -e PORT=$port $IMAGE) # -p :$port will establish a mapping of 12345->12345 from outside docker to # inside of docker. # Then, the application must observe the PORT environment variable # to launch itself on that port; This is set by -e PORT=$port. # Additional goodies: echo $id # <-- the running id of your container echo $id > /app/files/CONTAINER # <-- remember Docker id for this instance docker ps # <-- check that the app is running docker logs $id # <-- look at the output of the running instance docker kill $id # <-- to kill the app 

Método 1b Porta de aplicativo codificado

... se sua aplicação usa uma porta codificada, por exemplo, a porta 5000 (isto é, não pode ser configurada via variável de ambiente PORT, como no Método 1a), então ela pode ser codificada pelo Docker da seguinte forma:

 publicPort=12345 id=$(docker run -d -p $publicPort:5000 $IMAGE) # -p $publicPort:5000 will map port 12345 outside of Docker to port 5000 inside # of Docker. Therefore, nginx/apache must be configured to vhost proxy to 12345, # and the application within Docker must be listening on 5000. 

Método 2 (deixe Dokku descobrir as portas)

No momento, uma ótima opção para gerenciar o vhosts do Docker é o Dokku . Uma próxima opção pode ser usar o Flynn , mas a partir de agora o Flynn está apenas começando e ainda não está pronto. Portanto, vamos com o Dokku por enquanto: Depois de seguir as instruções de instalação do Dokku, para um único domínio, habilite vhosts criando o arquivo "VHOST":

 echo yourdomain.com > /home/git/VHOST # in your case: echo foo > /home/git/VHOST 

Agora, quando um aplicativo é enviado via SSH para o Dokku (veja os documentos do Dokku sobre como fazer isso), o Dokku irá olhar o arquivo VHOST e para o aplicativo em particular pressionado (digamos que você empurrou o "container-1"), ele irá gerar o seguinte arquivo:

 /home/git/container-1/nginx.conf 

E terá o seguinte conteúdo:

 upstream container-1 { server 127.0.0.1:49162; } server { listen 80; server_name container-1.yourdomain.com; location / { proxy_pass http://container-1; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $remote_addr; } } 

Quando o servidor for reinicializado, o Dokku irá garantir que o Docker inicie o aplicativo com a porta mapeada para sua porta inicialmente implementada (49162 aqui), em vez de ser atribuída aleatoriamente a outra porta. Para atingir essa atribuição determinística, o Dokku salva a porta inicialmente designada em /home/git/container-1/PORT e na próxima boot define o ambiente PORT para esse valor e também mapeia as atribuições de porta do Docker para essa porta em ambos os host-side e o lado do aplicativo. Isso se opõe ao primeiro lançamento, quando Dokku definirá PORT=5000 e, em seguida, descobrirá o que quer que seja a porta aleatória de mapas Dokku no lado do VPS para 5000 no lado do aplicativo. É redondo (e pode até mudar no futuro), mas funciona!

A maneira como o VHOST trabalha, sob o capô, é: ao fazer um git push do aplicativo via SSH, o Dokku irá executar ganchos que vivem em /var/lib/dokku/plugins/nginx-vhosts . Esses ganchos também estão localizados no código fonte do Dokku e são responsáveis ​​por gravar os arquivos nginx.conf com as configurações corretas do vhost. Se você não tiver esse diretório em /var/lib/dokku , tente executar dokku plugins-install .

Com a janela de encaixe, você deseja que os ips internos permaneçam normais (por exemplo, 80) e descubra como conectar as portas aleatórias.

Uma maneira de lidar com eles é com um proxy reverso, como o hipache. Aponte seu dns para ele e reconfigure o proxy conforme seus contêineres sobem e descem. Dê uma olhada em http://txt.fliglio.com/2013/09/protyping-web-stuff-with-docker/ para ver como isso pode funcionar.

Se você está procurando algo mais robusto, talvez queira dar uma olhada em “descoberta de serviço”. (uma olhada na descoberta de serviços com o docker: http://txt.fliglio.com/2013/12/service-discovery-with-docker-docker-links-and-beyond/ )

    Intereting Posts