简体   繁体   中英

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.

[ 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). I am fairly happy with my current conf.

[ my two apps ] Both are standalone applications (only requiring a db).

- official wordpress image. (-> new domain name)

-a django based app packed with a gunicorn server based on this tutorial (-> subdomain of an existing domain )

[ 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). If I bind then on standard ports, I'll have a conflict with my existing Apache.

How would you deal with it? Can I redirect to containers' internal ip with a mod_proxy of some kind? 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

Basically you configure your apache to forward requests to those services, ie:

<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

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

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

[ possible improvements ] I am not quite happy with port 8081 being visible from the external world. It means that the app could be accessed from this very port, bypassing the rules I setted up in apache.conf . I fixed the issue by adding an iptables rule

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.

\\//_

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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