Docker - Apache with Reverse Proxy in Bridged Network

The official docker image drupal:8.3.5-apache needs a few updates to work correctly with a reverse proxy or load balancer in a bridged network.  The main issue is REMOTE_ADDR will always be the docker gateway IP and REQUEST_SCHEME will be http when seen from inside the Apache docker container on port 80.


Option 1: Application level configuration (Drupal example)

Most apps allow configuring the public URL and/or reverse proxy settings.  

First do a "docker network inspect" on the network to get the gateway IP.  Alternatively, you can run this command inside the container:

ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print $2 }'

Next update the application specific settings.   Drupal 8 has reverse proxy settings in /sites/default/settings.php.   When 'reverse_proxy' is enabled, Drupal will use HTTP request headers (X-Forwarded-For,  X-Forwarded-Proto, etc...) to determine the host, port, and scheme of generated external URLs referring to itself.

$settings['reverse_proxy'] = TRUE;
$settings['reverse_proxy_addresses'] = array('172.0.0.1', '172.99.0.1'); 


Option 2: Add mod_rpaf to Apache 

If deploying more than just Drupal, configuration can be done at the apache level.  It will automatically adjust REMOTE_ADDR and misc headers using the standard remote proxy headers.  It is possible to extend the official drupal:apache by adding  just one line: RUN apt-get update && apt-get install libapache2-mod-rpaf. However, the distribution version of rpaf is limited in functionality.  Below is a Dockerfile that builds mod_rpaf from source and adds a startup script that configure the docker gateway as the trusted proxy address (for bridged networks).  

Project source: GitHubDocker Hub

FROM drupal:8.3.5-apache

MAINTAINER Paul Cinnamond

ENV TERM=xterm

RUN apt-get update \
     && apt-get upgrade -y \
     && apt-get install -y --no-install-recommends \
          ssmtp \
          vim \
          sudo \ 
     && apt-get clean \
     && rm -rf /var/lib/apt/lists/*

RUN { echo 'sendmail_path = "/usr/sbin/sendmail -t -i"'; } >> /usr/local/etc/php/php.ini

# sudo needed for php composer to run as www-data
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# build rpaf from github source
RUN apt-get update \
    && apt-get upgrade -y \
    && apt-get install -y build-essential apache2-threaded-dev unzip \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

RUN mkdir -p /usr/local/opt/rpaf 
ADD https://github.com/gnif/mod_rpaf/archive/stable.zip /usr/local/opt/rpaf
RUN cd /usr/local/opt/rpaf && unzip stable.zip
RUN cd /usr/local/opt/rpaf/mod_rpaf-stable && make && make install
ADD src/rpaf.load /etc/apache2/mods-available
ADD src/rpaf.conf /etc/apache2/mods-available

RUN apt-get remove -y --purge build-essential apache2-threaded-dev unzip

ADD src/startApache.sh /usr/local/bin
RUN chmod +x /usr/local/bin/startApache.sh

CMD ["/usr/local/bin/startApache.sh"]

 

Example NGINX configuration:
 

server {
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        server_name here.com;

        ssl_certificate /etc/letsencrypt/live/here.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/here.com/privkey.pem; 

        root /var/www/html;

        location / {
                proxy_pass http://127.0.0.1:8080;
                proxy_redirect off;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-Proto https;
                #proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
                proxy_set_header X-Scheme $scheme;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

}