Est-il possible d'utiliser Docker pour séparer les sites Web des utilisateurs?

12

Je gère des serveurs sur lesquels les utilisateurs ont leurs propres sites Web accessibles par FTP (comme une société d'hébergement) et au lieu de travailler sur l'isolement des processus de pile LAMP, je me demandais s'il était possible d'implémenter Docker et d'utiliser des images par site Web.

D'après ce que je comprends, vous pouvez exposer l'instance Docker via leurs ports, donc si vous exécutez deux instances Docker sur le même serveur, vous devrez exposer deux ports différents.

Mais est-il possible d'exporter non pas des ports, mais le nom du serveur, comme:

  • www.somewebsite.com: instance Docker 1
  • www.otherwebsite.com: Docker instance 2
  • www.etc.com: instance Docker ...

Et cela, sur le même serveur.

J'ai pensé à installer uniquement Apache sur le serveur, ce qui redirigerait la demande vers l'instance Docker dédiée en fonction du nom du serveur, mais ensuite je devrais installer Apache (à nouveau!) Et MySQL sur toutes les instances Docker.

Est-ce possible et en plus, est-ce intéressant en terme de performance (ou pas du tout)?

Merci de votre aide.

Cyril N.
la source
1
Théoriquement, c'est possible, Apache ferait un ProxyPass vers le port que chaque instance Docker écoute.
thanasisk

Réponses:

12

Oui c'est possible. Ce que vous devez faire, c'est fournir plusieurs 80 ports. un pour chaque URL. Vous pouvez le faire en utilisant, par exemple, l'hôte virtuel d'Apache exécuté sur le serveur hôte Docker.

  1. Définissez DNS CNAME.
  2. Exécutez les instances de docker et mappez leur port 80 sur le port, par exemple, 12345 ~ 12347 de l'hôte de docker.
  3. Exécutez le serveur Apache sur l'hôte docker et définissez un hôte virtuel pour chaque URL et définissez ProxyPass et ProxyPassReverse sur localhost: 12345 qui est l'une de vos instances de docker.

Le fichier de configuration Apache ressemblera à ceci:

<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
la source
4
Merci! Cela a beaucoup aidé. En outre, il y a le ProxyPreserveHost On, donc vous ne vous retrouvez pas avec beaucoup de liens vers local.hostname.ofDockerHost: 12345 insite votre site web. Voici plus d'informations qui m'ont été utiles: digitalocean.com/community/tutorials/…
Sebastián Ramírez
Docker enregistrera-t-il les modifications apportées à la base de données, etc.?
EminezArtus
3

C'est possible. Vous pouvez utiliser apache (ou mieux encore, haproxy, nginx ou vernis, qui peut être plus efficace qu'apache pour cette tâche de redirection uniquement) sur le serveur principal, pour rediriger vers les ports apache de chaque conteneur.

Mais, selon les sites que vous y exécutez (et leurs configurations apache), cela peut nécessiter beaucoup plus de mémoire que d'utiliser un seul apache central avec des hôtes virtuels, surtout si vous avez des modules (par exemple php) qui nécessitent beaucoup de RAM.

gmuslera
la source
Merci pour votre réponse. En effet, le service "d'hébergement" que je fournirai comprend des choses comme Prestashop, Wordpress, etc., donc, basé beaucoup sur PHP et des moteurs lourds (je parle plus de Prestashop ici).
Cyril N.
1
Un système d'hébergement virtuel Dockerized serait-il mieux modularisé en séparant PHP en ses propres conteneurs Docker et en faisant utiliser aux conteneurs Apache ce conteneur pour le traitement PHP? La même chose s'appliquerait-elle aux bases de données? Par exemple, avez-vous du trafic proxy hôte vers des conteneurs Apache (qui contiennent des sites Web d'utilisateurs), qui à leur tour envoient tous les traitements PHP vers un conteneur PHP et la base de données lit / écrit dans un conteneur MySQL? Ou le PHP serait-il moins gourmand en ressources de cette façon? PHP-FPM, SuPHP ou similaire fourniraient-ils le même type de configuration dans un environnement non Docker?
ojrask
PHP-FPM dans un conteneur serait au moins un peu redondant au niveau de l'espace: code.google.com/p/sna/wiki/NginxWithPHPFPM L'installation d'Apache / Nginx doit copier les fichiers PHP dans le conteneur PHP-FPM afin pour que ce système fonctionne. Un conteneur de données partagées monté résoudrait-il ce problème?
ojrask
Si vous avez besoin de partager des données (c'est-à-dire les fichiers php) entre conteneurs, les volumes sont le chemin à parcourir, vous pouvez les monter à partir d'autres conteneurs (même des fichiers dédiés aux données) ou du vrai système de fichiers. Le module apache était le moyen le plus rapide d'exécuter du code php, en avoir un juste pour php, pas des fichiers statiques, et avoir une couche supérieure pour fournir le contenu statique / pouvant être mis en cache (c'est-à-dire le vernis) pourrait être un bon combo.
gmuslera
3

Je sais que cela a déjà été répondu, mais je voulais aller plus loin et vous montrer un exemple de la façon dont cela pourrait être fait, pour fournir une réponse plus complète.

Veuillez voir mon image docker ici avec des instructions sur la façon de l'utiliser, cela vous montrera comment configurer deux sites https://hub.docker.com/r/vect0r/httpd-proxy/

Comme l'a dit jihun, vous devrez vous assurer que votre configuration de vhost est définie. Mon exemple utilise le port 80 pour afficher un site de test example.com et 81 pour afficher le site de test example2.com. Il est également important de noter que vous devrez spécifier votre contenu et exposer les ports requis dans votre Dockerfile, comme tel;

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"]

J'espère que cela explique un peu plus le processus. N'hésitez pas à me poser d'autres questions à ce sujet, heureux de vous aider.

Cordialement,

V

Vect0r
la source
J'ai également téléchargé les fichiers utilisés pour créer cette image sur github; github.com/V3ckt0r/docker-httpd-proxy
Vect0r
1

Dans mon cas, j'avais besoin d'ajouter SSLProxyEngine On , ProxyPreserveHost On et RequestHeader set Front-End-Https "On" à mon fichier vhost apache 2.4, parce que je voulais activer SSL sur le conteneur Docker. À propos de local.hostname.ofDockerHost , dans mon cas, le nom du serveur hôte exécutant le conteneur Docker était lucas , et le port mappé au port 443 du conteneur Docker était 1443 (car le port 443 était déjà utilisé par apache dans l'hôte). serveur), de sorte que cette ligne se soit terminée de cette façon https: // lucas: 1443 /

Ceci est la configuration finale, et cela fonctionne très bien!

<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>

Enfin, dans le conteneur Docker, je devais configurer des en-têtes SSL proxy. Dans mon cas, le conteneur exécutait nginx et quelque chose appelé omnibus pour configurer des applications ruby. Je pense que cela peut également être configuré dans un fichier de configuration nginx. Je vais l'écrire comme c'est le cas au cas où quelqu'un trouverait cela utile

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'

Guide complet pour apache, ISP Config, serveur Ubuntu 16.04 ici https://www.howtoforge.com/community/threads/subdomain-or-subfolder-route-requests-to-running-docker-image.73845/#post-347744

rasoir7
la source