É possível usar o Docker para separar sites da web para usuários?

12

Eu gerencio servidores nos quais os usuários têm seus próprios sites que podem ser acessados ​​por FTP (como uma empresa de hospedagem) e, em vez de trabalhar no isolamento de processos de pilha LAMP, fiquei pensando se seria possível implementar o Docker e usar imagens por site.

Pelo que entendi, você pode expor a instância do Docker por meio de suas portas; portanto, se você executar duas instâncias do Docker no mesmo servidor, precisará expor duas portas diferentes.

Mas é possível exportar não portas, mas o nome do servidor, como:

  • www.somewebsite.com: instância 1 do Docker
  • www.otherwebsite.com: instância 2 do Docker
  • www.etc.com: instância do Docker ...

E isso, no mesmo servidor.

Pensei em instalar apenas o Apache no servidor, que redirecionaria a solicitação para a instância dedicada do Docker com base no nome do servidor, mas teria que instalar o Apache (novamente!) E o MySQL em qualquer instância do Docker.

Isso é possível e, além disso, isso é interessante em termos de desempenho (ou não existe)?

Obrigado pela ajuda.

Cyril N.
fonte
1
Teoricamente, é possível que o Apache faça um ProxyPass para a porta que cada instância do Docker está escutando.
thanasisk

Respostas:

12

Sim, é possível. O que você precisa fazer é fornecer várias 80 portas. um para cada URL. Você pode fazer isso usando, por exemplo, Host virtual do Apache em execução no servidor host do Docker.

  1. Defina DNS CNAME.
  2. Execute instâncias do docker e mapeie sua porta 80 para a porta, digamos, 12345 ~ 12347 do host do docker.
  3. Execute o servidor Apache no host do docker e defina um Host virtual para cada URL e defina ProxyPass e ProxyPassReverse como localhost: 12345, que é uma das instâncias do docker.

O arquivo de configuração do Apache ficará assim:

<VirtualHost *:80>
ServerName www.somewebsite.com
  <Proxy *>
    Allow from localhost
  </Proxy>
  ProxyPass        / http://local.hostname.ofDockerHost:12345/
  ProxyPassReverse / http://local.hostname.ofDockerHost:12345/
</VirtualHost>
Jihun
fonte
4
Obrigado! Isso ajudou muito. Além disso, existe o ProxyPreserveHost On, para que você não tenha muitos links para local.hostname.ofDockerHost: 12345 no seu site. Aqui estão mais informações que foram úteis para mim: digitalocean.com/community/tutorials/…
Sebastián Ramírez
O docker salvará as alterações no banco de dados, etc.?
EminezArtus
3

É possível. Você pode usar o apache (ou, melhor ainda, haproxy, nginx ou verniz, que pode ser mais eficiente que o apache apenas para essa tarefa de redirecionamento) no servidor principal, para redirecionar para as portas apache de cada contêiner.

Mas, dependendo dos sites que você executa lá (e de suas configurações do apache), isso pode exigir muito mais memória do que usar um único apache central com virtualhosts, especialmente se você tiver módulos (por exemplo, php) que exigem muita memória RAM.

gmuslera
fonte
Obrigado pela sua resposta. De fato, o serviço de "hospedagem" que fornecerei inclui coisas como Prestashop, Wordpress, etc., portanto, muito baseado em PHP e mecanismos pesados ​​(estou falando mais sobre Prestashop aqui).
Cyril N.
1
Um sistema de hospedagem virtual Dockerized seria melhor modularizado, separando o PHP em seus próprios contêineres Docker e fazendo com que os contêineres Apache usassem esse contêiner para processamento PHP? O mesmo se aplica aos bancos de dados? Por exemplo, possui tráfego de proxy de host para contêineres Apache (que contêm sites de usuários), que por sua vez enviam todo o processamento PHP para um contêiner PHP e o banco de dados lê / grava em um contêiner MySQL? Ou o PHP seria menos faminto por recursos dessa maneira? O PHP-FPM, SuPHP ou similar forneceria o mesmo tipo de configuração em um ambiente não Docker?
ojrask
O PHP-FPM em um contêiner seria pelo menos um pouco redundante em termos de espaço para arquivo : code.google.com/p/sna/wiki/NginxWithPHPFPM A instalação do Apache / Nginx precisa copiar os arquivos PHP para o contêiner PHP-FPM para para este sistema funcionar. Um contêiner de dados compartilhado montado resolveria esse problema?
ojrask
Se você precisar compartilhar dados (isto é, os arquivos php) entre contêineres, os volumes são o caminho a percorrer, você poderá montá-los a partir de outros contêineres (até mesmo com dados dedicados) ou do sistema de arquivos real. O módulo apache costumava ser a maneira mais rápida de executar código php, tendo apenas um para php, não arquivos estáticos, e tem uma camada superior para fornecer o conteúdo estático / armazenável em cache (verniz Ie) poderia ser uma boa combinação.
gmuslera
3

Sei que isso já foi respondido, mas queria dar um passo adiante e mostrar um exemplo de como isso pode ser feito, para fornecer uma resposta mais completa.

Por favor, veja minha imagem do docker aqui com instruções sobre como usá-lo. Isso mostrará como configurar dois sites https://hub.docker.com/r/vect0r/httpd-proxy/

Como o jihun disse, você terá que garantir que a sua configuração de vhost esteja definida. Meu exemplo usa a porta 80 para exibir um site de teste example.com e 81 para exibir o site de teste example2.com. Também é importante observar que você precisará especificar seu conteúdo e expor as portas necessárias no seu Dockerfile, como tal;

FROM centos:latest
Maintainer vect0r
LABEL Vendor="CentOS"

RUN yum -y update && yum clean all
RUN yum -y install httpd && yum clean all

EXPOSE 80 81

#Simple startup script to aviod some issues observed with container restart
ADD run-httpd.sh /run-httpd.sh
RUN chmod -v +x /run-httpd.sh

#Copy config file across
COPY ./httpd.conf /etc/httpd/conf/httpd.conf
COPY ./example.com /var/www/example.com
COPY ./example2.com /var/www/example2.com
COPY ./sites-available /etc/httpd/sites-available
COPY ./sites-enabled /etc/httpd/sites-enabled

CMD ["/run-httpd.sh"]

Espero que isso ajude a explicar um pouco mais o processo. Por favor, não hesite em perguntar-me mais sobre isso, prazer em ajudar.

Saudações,

V

Vect0r
fonte
Também carreguei os arquivos usados ​​para criar esta imagem no github; github.com/V3ckt0r/docker-httpd-proxy
Vect0r
1

No meu caso, eu precisava adicionar SSLProxyEngine On , ProxyPreserveHost On e RequestHeader, definir Front-End-Https "On" no meu arquivo apache 2.4 vhost, porque queria ativar o SSL no contêiner do docker. Sobre o local.hostname.ofDockerHost , no meu caso, o nome do servidor host executando o contêiner do docker era lucas e a porta mapeada para a porta 443 do contêiner do docker era 1443 (porque a porta 443 já estava em uso pelo apache no host server), para que a linha acabasse assim https: // lucas: 1443 /

Esta é a configuração final e está funcionando muito bem!

<VirtualHost *:443> # Change to *:80 if no https required
    ServerName www.somewebsite.com
    <Proxy *>
        Allow from localhost
    </Proxy>
    SSLProxyEngine On # Comment this out if no https required
    RequestHeader set Front-End-Https "On" # Comment this out if no https required
    ProxyPreserveHost    On
    ProxyPass        / http://local.hostname.ofDockerHost:12345/
    ProxyPassReverse / http://local.hostname.ofDockerHost:12345/
</VirtualHost>

Finalmente, no contêiner do docker, tive que configurar os cabeçalhos SSL do proxy. No meu caso, o contêiner estava executando o nginx e algo chamado omnibus para configurar aplicativos ruby. Eu acho que isso pode ser configurado em um arquivo de configuração nginx também. Anotá-lo-á como é o caso de alguém achar isso útil

nginx['redirect_http_to_https'] = true
nginx['proxy_set_headers'] = {
    "Host" => "$http_host",
    "X-Real-IP" => "$remote_addr",
    "X-Forwarded-For" => "$proxy_add_x_forwarded_for",
    "X-Forwarded-Proto" => "https",
    "X-Forwarded-Ssl" => "on"
}
nginx['real_ip_trusted_addresses'] = ['10.0.0.77'] # IP for lucas host
nginx['real_ip_header'] = 'X-Real-IP'
nginx['real_ip_recursive'] = 'on'

Guia completo para apache, ISP Config, servidor Ubuntu 16.04 aqui https://www.howtoforge.com/community/threads/subdomain-or-subfolder-route-requests-to-running-docker-image.73845/#post-347744

razor7
fonte