Docker + Nginx reverse proxy + Apache2 + Moodle

Docker + Nginx reverse proxy + Apache2 + Moodle

by Kevin Poulsen -
Number of replies: 3

We're setting up a few applications (Moodle, MediaWiki, Gitlab, etc.) in the following Docker environment:


Nginx is in a container and is serving as a Reverse  Proxy to the applications in other containers on the same host.  They share MariaDB in one container and openLDAP in another container.  The internal DNS name for the Moodle container is:  "classrooms".


For the Moodle container, I started with a stock Ubuntu 14.04 container and manually installed required services, then pulled Moodle 3.1 stable using Git.  I followed reverse proxy configuration instructions from these two sources:

https://docs.moodle.org/22/en/Reverse_proxy_frontend

https://www.nginx.com/resources/wiki/start/topics/examples/likeapache


The relevant settings in the Moodle config.php are:

$CFG->wwwroot   =[removed to avoid triggering the community spam filters.  it’s:  https : // classrooms  .authenticity  .ac ]

$CFG->reverseproxy = true;

$CFG->sslproxy = true;

I've noticed that instructions for using a reverse proxy with Moodle 2.X also include this variable:  $CFG->loginhttps=1;  However, it isn't included in the 3.x config.php file.  I've tried with and without:  it doesn't seem to make a difference, so this has been left out.


With those settings, I get this error:

“Reverse proxy enabled, server can not be accessed directly, sorry.

Please contact server administrator.”


If I remove the https:// from wwwroot, then I get Moodle without CSS.  So, I know that I'm close to having this correct.  Any idea why the "correct" setting would not work?

$CFG->wwwroot   = 'classrooms.authenticity.ac';


Here's the http configuration for Nginx (I've checked for a trailing space):

server \{

        listen 80;

        server_name classrooms.authenticity.ac;


    set $backend "[removed to avoid triggering the community spam filters]";

    set $backendPort "80";


    location / \{


    proxy_set_header Host $host;

    proxy_set_header X-Real-IP $remote_addr;


        proxy_set_header X-Forwarded-Host $backend:$backendPort;

        proxy_set_header X-Forwarded-Server $backend;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


    proxy_pass $backend;

    \}



 # return 301 [removed to avoid triggering the community spam filters]; # enforce https

}



And, here’s the https configuration:


server \{

  resolver 172.17.42.1;

  listen 443 ssl;

  server_name classrooms.authenticity.ac;

  #ssl_certificate     [redacted]

  #ssl_certificate_key [redacted]

  ssl_certificate     [redacted]

  ssl_certificate_key [redacted]


    set $backend "[removed to avoid triggering the community spam filters:  it’s: http : // classrooms]”;

    set $backendPort "80";


  location / {

    proxy_set_header Host $host;

    proxy_set_header X-Real-IP $remote_addr;


        proxy_set_header X-Forwarded-Host $backend:$backendPort;

        proxy_set_header X-Forwarded-Server $backend;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


    proxy_pass $backend;

  }

}


Average of ratings: -
In reply to Kevin Poulsen

Re: Docker + Nginx reverse proxy + Apache2 + Moodle

by Matteo Scaramuccia -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers

Hi Kevin,
why not using nginx + PHP-FPM?
No need to configure a "reverse proxy" as understood by Moodle but https://docs.moodle.org/31/en/Nginx.

HTH,
Matteo

In reply to Matteo Scaramuccia

Re: Docker + Nginx reverse proxy + Apache2 + Moodle

by Kevin Poulsen -

If we weren't looking for the efficiency, scalability and load balancing offered by the Blowb stack on Docker, then your suggestion would be good.  Having selected this stack, we're interested in getting Moodle, Wikimedia and other apps to work. 

We have some additional information on this issue.  Some diagnostics revealed these malformed URLs:

https://classrooms.authenticity.ac/classrooms.authenticity.ac/theme/yui_combo.php?rollup/3.17.2/yui-moodlesimple-min.css 

https://classrooms.authenticity.ac/classrooms.authenticity.ac/theme/styles.php/clean/1472617756/all 

https://classrooms.authenticity.ac/classrooms.authenticity.ac/theme/yui_combo.php?rollup/3.17.2/yui-moodlesimple-min.js&rollup/1472617756/mcore-min.js 

https://classrooms.authenticity.ac/classrooms.authenticity.ac/lib/javascript.php/1472617756/lib/javascript-static.js 


That's enough to show a very clear pattern.  "classrooms.authenticity.ac/" is added to the URL twice.  When the database was originally created, the wwwroot was "classrooms.authenticity.ac".  We've since changed the wwwroot to "https://classrooms.authenticity.ac" per the instructions for reverse proxy configuration.  I'm wondering whether the URL is being formed by the wwwroot + [something from the database] + [content url]


Moodle 1.x and 2.x have had similar bugs:

https://tracker.moodle.org/browse/MDL-24453

https://tracker.moodle.org/browse/MDL-24705

https://moodle.org/mod/forum/discuss.php?d=188126

https://tracker.moodle.org/browse/MDL-27688

and more.


I'm not the only person who has experienced this problem.  Are there specific settings to fix?  Or, is this a genuine bug?



In reply to Kevin Poulsen

Re: Docker + Nginx reverse proxy + Apache2 + Moodle

by Kevin Poulsen -

An update:  Found the problem!!  


To repeat the symptom - Moodle resource URLs are displaying like this:

https://classrooms.authenticity.ac/moodle/classrooms.authenticity.ac/moodle/admin/index.php


Even after deleting the Moodle database, the duplicate domain name kept appearing in URLs.  So, it wasn’t coming from the database,.  


In most of my diagnosis, it was impossible to tell whether the duplicate stuff was coming from the config.php or from the reverse proxy itself.  So, I made them different:  It wasn’t coming from config.php.  


There were two things that could be happening at this point:  The reverse proxy was assembling the URL incorrectly, or Moodle was using proxy header information to create the incorrect URL.  The install page works fine when the config.php file isn’t there.  So, Moodle appears to be handling the proxy header data incorrectly.  So, in the Nginx classrooms.tls.conf, I eliminated the host info in the header:   proxy_set_header Host ‘';  And, everything works well.  


Not sure whether this is a true bug in Moodle.  I hope this helps other community members. 

Average of ratings: Useful (2)