简体   繁体   English

将 Docker 容器应用程序与现有的 Apache Web 服务器连接起来

[英]Interfacing Docker containers apps with an existing Apache web server

I am fairly new to Docker and I have some trouble to understand how to make my "contained" apps accessible from the internet.我对 Docker 相当陌生,我在理解如何使我的“包含”应用程序可从 Internet 访问时遇到了一些麻烦。

[ my current configuration ] two web sites (in /var/www/html) + standard Apache + some tweeking I would like to be applied to everything new I deploy (headers CSP based rewriting, SSL certificate renewal with Certbot , etc etc). [我当前的配置] 两个网站(在 /var/www/html 中)+ 标准 Apache + 一些 tweeking 我想应用于我部署的所有新内容(基于头 CSP 的重写,使用Certbot续签 SSL 证书等)。 I am fairly happy with my current conf.我对我目前的 conf 相当满意。

[ my two apps ] Both are standalone applications (only requiring a db). [我的两个应用程序] 都是独立的应用程序(只需要一个数据库)。

- official wordpress image. -官方 wordpress图像。 (-> new domain name) (-> 新域名)

-a django based app packed with a gunicorn server based on this tutorial (-> subdomain of an existing domain ) - 一个基于 django 的应用程序,包含基于本教程的 gunicorn 服务器(-> 现有域的子域)

[ the issue ] If I bind both apps on, say, ports 8080 and 8000, browsers wont be able to reach it, for DNS servers do not handle ports (from what I understood, correct me if I am wrong). [问题] 如果我将两个应用程序都绑定到端口 8080 和 8000 上,浏览器将无法访问它,因为 DNS 服务器不处理端口(据我所知,如果我错了,请纠正我)。 If I bind then on standard ports, I'll have a conflict with my existing Apache.如果我在标准端口上绑定,则会与现有的 Apache 发生冲突。

How would you deal with it?你会怎么处理? Can I redirect to containers' internal ip with a mod_proxy of some kind?我可以使用某种mod_proxy重定向到容器的内部 IP 吗? Is there a cleaner-easier-safer way to do it?有没有更清洁、更简单、更安全的方法来做到这一点?

<VirtualHost *:443>
    ServerName sub.mydomain.io
    Redirect "/" "http://172.17.0.2/"

    ErrorLog /var/log/apache2/error.zarebski.io.com.log
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/mydomain.io/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/mydomain.io/privkey.pem
</VirtualHost>

In case of multiple applications running on different ports and different local IP addresses the recommended method is using Reverse Proxy如果多个应用程序运行在不同的端口和不同的本地 IP 地址上,推荐的方法是使用 反向代理

Basically you configure your apache to forward requests to those services, ie:基本上,您将 apache 配置为将请求转发到这些服务,即:

<VirtualHost *:443>
    ServerName sub.mydomain.io
    ProxyPass "/wordpress" "http://172.17.0.2:8080/"
    ProxyPass "/django" "http://172.17.0.2:8000/"

    ErrorLog /var/log/apache2/error.mydomain.io.com.log
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/mydomain.io/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/mydomain.io/privkey.pem
</VirtualHost>

If you have multpile external domain you can use Name Based Virtual hosts如果您有多个外部域,您可以使用基于名称的虚拟主机

Well, it took me a while to figure things out, for there was two main corner cases.好吧,我花了一段时间才弄明白,因为有两个主要的角落案例。 I'll stick to one case: the wordpress image我将坚持一个案例: wordpress 图像

<VirtualHost *:443>
    ServerName new_domain.eu
    ProxyPass / http://localhost:8081/

    <Location />
            AddOutputFilterByType SUBSTITUTE text/html
            SetOutputFilter proxy-html
            ProxyPassReverse /
            Substitute "s|http://localhost:8081/|https://new_domain.eu/|i"
            RequestHeader    unset  Accept-Encoding
    </Location>

    SSLCertificateFile /etc/letsencrypt/live/new_domain.eu/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/new_domain.eu/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>

[ First of all ], I could not access container from their local ip (ie 172.7.0.3:80, not sure why), so I used the localhost port defined while setting the container up: [首先],我无法从他们的本地 IP访问容器(即 172.7.0.3:80,不知道为什么),所以我使用了在设置容器时定义的 localhost 端口:

docker run -e WORDPRESS_DB_PASSWORD=thePassWord --name wordpress --link wordpressdb:mysql -p 8081:80 -v "$PWD/html":/var/www/html -d wordpress

[ secondly ] the tricky part was, then, to handle properly relative urls (eg some/path/to/css), for these were not accessible. [其次] 棘手的部分是正确处理相对 url(例如 some/path/to/css),因为这些是不可访问的。 Apparently, this is a well known issue .显然,这是一个众所周知的问题 This part was the longest: things changed a lot around Apache 2.4 and the syntax is not well documented.这部分是最长的:围绕 Apache 2.4 发生了很大变化,并且语法没有很好的文档记录。 Basically,基本上,

Substitute "s|http://localhost:8081/|https://new_domain.eu/|i" 

replace all urls in html so that relative resources (css, js, png, etc etc) could be properly accessed.替换 html 中的所有 url,以便可以正确访问相关资源(css、js、png 等)。

[ possible improvements ] I am not quite happy with port 8081 being visible from the external world. [可能的改进] 我对从外部世界可见的端口 8081 不太满意。 It means that the app could be accessed from this very port, bypassing the rules I setted up in apache.conf .这意味着可以从这个端口访问该应用程序,绕过我在apache.conf 中设置的规则。 I fixed the issue by adding an iptables rule我通过添加iptables 规则解决了这个问题

iptables -A INPUT -p tcp -s localhost --dport 8081 -j ACCEPT
iptables -A INPUT -p tcp --dport 8081 -j DROP

Not quite elegant so if anyone has a suggestion, let me know.不太优雅,所以如果有人有建议,请告诉我。

\\//_ \\//_

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM