Docker: Improve reverse_proxy_addresses handling
Created by: Florent Torregrosa
https://drupalfrance.slack.com/archives/CMQ8YKM2N/p1591463917167900
Imported comments:
By Florent Torregrosa on 2020-10-03T21:42:22.042Z
changed title from Improve reverse_proxy_addresses handling in Docker to Docker: Improve reverse_proxy_addresses handling
By Florent Torregrosa on 2020-09-10T13:57:18.018Z
For the record:
dns_get_record('varnish', DNS_A);
Works, but it has performance implication.
Thanks Frédéric ;)
By Florent Torregrosa on 2020-07-05T22:07:47.958Z
Current situation:
- Request -> Traefik (HTTPS) -> Apache (HTTP)
- Request -> Traefik (HTTPS) -> Varnish (HTTP) -> Apache
The problem is that for Drupal (ReverseProxyMiddleware / Symfony HTTP Foundation) to understand the request is secure, the REMOTE_ADDR IP must be among the a list of reverse_proxy_addresses IPs in the settings.php.
When calling Apache directly, REMOTE_ADDR = 172.XX.0.1 (not 172.17.0.1), the docker-compose network's gateway. Because Traefik is used in network_mode: host
, so viewed as on the host and without dedicated IP.
When calling on the Varnish domain, REMOTE_ADDR = 172.XX.0.Y (the Varnish container IP).
And now the real problems:
- how to dynamically get those IPs?
- how to do that in a way that scaling will still be possible?
So, let's say with some command line tools (https://www.2daygeek.com/linux-command-find-check-domain-ip-address) it is possible to alter the entrypoint of the web service to get the Varnish service containers IPs and to change the settings.php at each start, new problems:
- chicken and egg: the
varnish
service depends on theweb
service because of the probe in the Varnish configuration (also the Varnish config is not working when trying to scale theweb
service, see #99). And if thevarnish
service is not started yet when theweb
service will start, no IP to detect and inject... - about scaling, theorically, we should be able to scale the varnish service (or any service) anyway we want. This is the feature of autoscaling for example (I know I am far from it). So if new varnish containers are created, its IP addresses should be added to the new and existing web service containers... And there is no "event" entry in the docker-compose file. There are events https://docs.docker.com/engine/reference/commandline/events/, but it seems to need very manual scripts https://gist.github.com/zulhfreelancer/85fa0e746beb68e1f355db68821bf970 to interact with. I need to test if it is possible to change an environment variable with that.
If it will be possible, It will be hard but not impossible. If not possible, I will close this problem and stay with the current situation.
Because there is still the problem, if calling Apache directly, the REMOTE_ADDR is the gateway. The Traefik do not have IP address. So it means, I should have an Nginx as SSL reverse-proxy like this:
- Request -> Traefik -> Nginx (HTTPS) -> Apache (HTTP)
- Request -> Traefik -> Nginx (HTTPS) -> Varnish (HTTP) -> Apache
I think it is an under-usage of Traefik. Also now that I am in a stable handling of SSL/HTTPS with https://gitlab.com/florenttorregrosa-docker/apps/docker-traefik that is able to become common to local environments. It will require to rethink all the scripts and process. Generating certificates per project to allow Nginx to use it and I don't know if Traefik will not block self-signed certificates at this moment.
Being able to reach the website with Apache directly is handy in case you need to debug external caches like Varnish, so I don't want to lose this capability.
I wonder how it is done on production environments with Kubernetes and other orchestration tools for example.