Configuring the Router: Difference between revisions

From MoodleDocs
No edit summary
No edit summary
Line 1: Line 1:
{{Installing Moodle}}
{{Installing Moodle}}
Moodle includes a Routing Engine which allows requests to be dynamically served without files in specific locations.
''This page is intended to help systems administrators to correctly configure the Routing Engine created as a part of Moodle 4.5.''
 
From Moodle 4.5 onwards, Moodle includes a Routing Engine which allows requests to be dynamically served without files in specific locations.


The use of these routes can help to provide nicer URLs, which are easier to remember and more user-friendly. This is also reported to assist with SEO ranking.
The use of these routes can help to provide nicer URLs, which are easier to remember and more user-friendly. This is also reported to assist with SEO ranking.


While earlier versions described routing as a requirement from Moodle 5.1 onwards, this has been revised. Routing is '''strongly recommended''' for new and upgraded sites, but it is not compulsory. Moodle includes a compatibility shim that allows sites to continue operating without routing configured.
Configuration of the Moodle Router will be compulsory from Moodle 5.1 onwards.
 
Administrators are encouraged to enable routing to take full advantage of the new architecture and to ensure long-term compatibility with future Moodle releases.


The type of Router that Moodle uses is known as a Front Controller.
The type of Router that Moodle uses is known as a Front Controller.
Line 28: Line 28:
=== Configuring Apache2 ===
=== Configuring Apache2 ===


==== Without Root Access ====
This process requires root access.  Apache2 can be configured to support the Moodle Router by specifying a [https://httpd.apache.org/docs/trunk/mod/mod_dir.html#fallbackresource <code>FallbackResource</code>] in the <code>[https://httpd.apache.org/docs/2.4/mod/core.html#directory Directory]</code> directiveIf not already defined, also add the <code>DirectoryIndex index.php</code> [https://httpd.apache.org/docs/2.4/mod/mod_dir.html#directoryindexdirective directive] directly above the <code>[https://httpd.apache.org/docs/trunk/mod/mod_dir.html#fallbackresource FallbackResource]</code> directive to prevent HTTP 404 errors from occurring with the Moodle Router.<syntaxhighlight lang="apacheconf">
The easiest way to configure Apache2 does not require root access.  In the main moodle directory, open (or create) the .htaccess file.  Add the following line to the start of the file (it may also work at other places in that file).
 
<code>FallbackResource /r.php</code>
 
The [https://httpd.apache.org/docs/trunk/mod/mod_dir.html#fallbackresource <code>FallbackResource</code>] directive sets a handler for any URL that doesn't map to anything in your filesystem.  The handler, <code>r.php</code>, is already present in the main moodle directory.
 
==== With Root Access ====
Changing the Apache2 configuration file requires root access.  This may be worth the extra work because Apache indicates that using .htaccess instead of a configuration file will result in a [https://httpd.apache.org/docs/2.4/howto/htaccess.html#when performance hit].  The location of the configuration fill may be found with the command <code>httpd -V</code>; if that doesn't work, [https://cwiki.apache.org/confluence/display/httpd/DistrosDefaultLayout common locations] are given by Apache, and commands to find the location are given on [https://stackoverflow.com/questions/13341210/how-can-i-find-out-where-the-httpd-conf-file-is-located stackoverflow]Part of the output of <code>httpd -V</code> is shown below.
<syntaxhighlight lang="apacheconf">
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT=256
-D HTTPD_ROOT="/etc/apache2"
-D SUEXEC_BIN="/usr/sbin/suexec"
-D DEFAULT_PIDLOG="/var/run/apache2/httpd.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="conf/mime.types"
-D SERVER_CONFIG_FILE="conf/httpd.conf"
</syntaxhighlight>
 
The data in the third and last lines, HTTPD_ROOT, and SERVER_CONFIG_FILE, can be combined to give the location of httpd.conf, which in this case is <code>/etc/apache2/conf/httpd.conf</code>.  Change to the directory containing that file and run the command <code>grep -i moodle httpd.conf</code>.  This will list all the lines—about 20—containing "moodle" in the file (the "-i" makes the search case insensitive).  Find and save (in some other application) the appropriate versions of the following two lines, which contain the [https://httpd.apache.org/docs/2.4/mod/core.html#DocumentRoot DocumentRoot] and<code>[https://httpd.apache.org/docs/2.4/mod/core.html#directory Directory]</code>directives. <syntaxhighlight lang="apacheconf">
DocumentRoot /home/USER/public_html/moodle
<Directory "/home/USER/public_html/moodle">
</syntaxhighlight>
Rather than editing the <code>httpd.conf</code> file, changes are made with the <code>Include</code> directive.  When Apache is updated, the <code>httpd.conf</code> file may be recreated, but the changes in Include files will still be available.  For details on changing the include files, it is recommended to check the documentation for your system.  The following example is for the web hosting control panel, cPanel.
 
Among the twenty lines mentioned above, also save the "Include" line that contains "ssl", rather than "std".
<syntaxhighlight lang="apacheconf">
# Include "/etc/apache2/conf.d/userdata/ssl/2_4/USER/moodle.example.org/*.conf"
</syntaxhighlight>
Note that "USER" is to be replaced by the actual user's name.  Also, the "Include" statement is commented out in this example, because no matching file has been found at the given location (cPanel will automatically uncomment the statement if a file is found at that location).  Navigate to the location of the expected *.conf file.  Beyond the 2_4 directory, you will probably have to use "<code>mkdir</code>" to create the other sub directories (that is, "USER", and "moodle.example.org" directories).  In that last directory, create a file, such as includeRoute.conf.  Add to the file the first two lines saved above, plus the last five lines shown here, so that the content resembles the following.
 
<syntaxhighlight lang="apacheconf">
DocumentRoot /home/user/public_html/moodle
<Directory "/home/user/public_html/moodle">
    AllowOverride None
    Require all granted
    DirectoryIndex index.php
    FallbackResource /moodle/r.php
</Directory>
</syntaxhighlight>
 
The argument to the[https://httpd.apache.org/docs/trunk/mod/mod_dir.html#fallbackresource <code>FallbackResource</code>] directive may have to be changed to just /r.php if moodle is not a subdomain (i.e., not moodle.example.com).  The <code>DirectoryIndex index.php</code> [https://httpd.apache.org/docs/2.4/mod/mod_dir.html#directoryindexdirective directive] is to prevent HTTP 404 errors from occurring with the Moodle Router.  The <code>[https://httpd.apache.org/docs/2.4/mod/mod_authz_core.html#require Require all granted]</code> directive allows unconditional access to authenticated users.  After saving the file, run the following two cPanel commands to update the system.
 
<syntaxhighlight lang="apacheconf">
/usr/local/cpanel/scripts/rebuildhttpdconf
/usr/local/cpanel/scripts/restartsrv_httpd
</syntaxhighlight>
If not using cPanel, httpd can be [https://httpd.apache.org/docs/current/stopping.html#graceful restarted] with <code>apachectl -k graceful</code>.  A command equivalent to "rebuildhttpdconf" may not be needed; check your system's documentation.
 
Here is another example of the include file. <syntaxhighlight lang="apacheconf">
DocumentRoot /var/www/moodle/public
DocumentRoot /var/www/moodle/public
<Directory /var/www/moodle/public>
<Directory /var/www/moodle/public>
Line 89: Line 38:
</syntaxhighlight>
</syntaxhighlight>


The <code>FallbackResource</code> is relative to the [https://httpd.apache.org/docs/2.4/mod/core.html#DocumentRoot DocumentRoot] so if Moodle is in a sub-directory, the path will be relative to that root.  
The <code>FallbackResource</code> is relative to the [https://httpd.apache.org/docs/2.4/mod/core.html#DocumentRoot DocumentRoot] so if Moodle is in a sub-directory, the path will be relative to that root. The <code>[https://httpd.apache.org/docs/2.4/mod/mod_authz_core.html#require Require all granted]</code> directive allows unconditional access to authenticated users.


<syntaxhighlight lang="apacheconf">
<syntaxhighlight lang="apacheconf">
Line 100: Line 49:
</Directory>
</Directory>
</syntaxhighlight>
</syntaxhighlight>
==== Without Root Access ====
Another way to configure Apache2 is using .htaccess but this is not the recommended approach and not tested regularly by Moodle HQ.
In the 'public' directory, open (or create) the .htaccess file.  Add the following line to the start of the file (it may also work at other places in that file).
<code>FallbackResource /r.php</code>
The [https://httpd.apache.org/docs/trunk/mod/mod_dir.html#fallbackresource <code>FallbackResource</code>] directive sets a handler for any URL that doesn't map to anything in your filesystem.  The handler, <code>r.php</code>, is already present in the main moodle directory.


===Configuring Nginx===
===Configuring Nginx===
Line 107: Line 67:
<syntaxhighlight lang="nginx">
<syntaxhighlight lang="nginx">
location / {
location / {
     try_files $uri $uri/ /r.php$is_args$args;
     try_files $uri /r.php;
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 115: Line 75:
<syntaxhighlight lang="nginx">
<syntaxhighlight lang="nginx">
location /moodle/ {
location /moodle/ {
   try_files $uri $uri/ /moodle/r.php$is_args$args;
   try_files $uri $uri/ /moodle/r.php;
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 123: Line 83:
<syntaxhighlight lang="nginx">
<syntaxhighlight lang="nginx">
location ~ ^/(?<sitepath>[^/]*)/ {
location ~ ^/(?<sitepath>[^/]*)/ {
   try_files $uri $uri/ /$sitepath/r.php$is_args$args;
   try_files $uri $uri/ /$sitepath/r.php;
}
}
</syntaxhighlight>
</syntaxhighlight>
Line 129: Line 89:
===IIS===
===IIS===


Note: The following instructions have received limited testing, but may not cover every scenario. If you have knowledge of IIS and can provide more accurate or up-to-date instructions, please do so.
Note: The following instructions are untested. If you have knoweldge of IIS and can provide more accurate or up-to-date instructions, please do so.


Using the [https://www.iis.net/downloads/microsoft/url-rewrite URL Rewriter] module for IIS, you can create a Rewrite rule in your <code>web.config</code> file.
Using the [https://www.iis.net/downloads/microsoft/url-rewrite URL Rewriter] module for IIS, you can create a Rewrite rule in your <code>web.config</code> file.
Line 136: Line 96:
<rewrite>
<rewrite>
     <rules>
     <rules>
         <rule name="Moodle Routing Engine" enabled="true" stopProcessing="true">
         <rule name="Moodle" stopProcessing="true">
             <match url="^(.*)$" ignoreCase="true" />
             <match url="^(.*)$" ignoreCase="false" />
             <conditions logicalGrouping="MatchAll">
             <conditions logicalGrouping="MatchAll">
                <!-- Only rewrite when the target is NOT a real file or directory -->
                 <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
                 <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
             </conditions>
             </conditions>
            <!-- Keep any ?query=params; IIS/PHP will still expose the original path via REQUEST_URI -->
             <action type="Rewrite" url="r.php" appendQueryString="true" />
             <action type="Rewrite" url="r.php" appendQueryString="true" />
         </rule>
         </rule>
Line 150: Line 107:
</syntaxhighlight>
</syntaxhighlight>


==Configuring Moodle==
== Configuring Moodle ==


After successfully configuring the Router, you should inform Moodle that it is correctly configured by setting the following in your <code>config.php</code>
After successfully configuring the Router, you should inform Moodle that it is correctly configured by setting the following in your <code>config.php</code>
Line 160: Line 117:
Remove the "my/" from the address and it should take you to the appropriate page.
Remove the "my/" from the address and it should take you to the appropriate page.
[[es:Configuración del Router]]
[[es:Configuración del Router]]
[[de:Router konfigurieren]]

Revision as of 02:28, 23 January 2026

This page is intended to help systems administrators to correctly configure the Routing Engine created as a part of Moodle 4.5.

From Moodle 4.5 onwards, Moodle includes a Routing Engine which allows requests to be dynamically served without files in specific locations.

The use of these routes can help to provide nicer URLs, which are easier to remember and more user-friendly. This is also reported to assist with SEO ranking.

Configuration of the Moodle Router will be compulsory from Moodle 5.1 onwards.

The type of Router that Moodle uses is known as a Front Controller.

What the web server needs to do

In many cases a user will request a file which is available as requested on disk, for example if the user requests https://example.com/course/view.php?id=42 then this will relate to a file at /course/view.php.

However, in other cases, a user may be accessing a URL which does not directly relate to a file on disk, for example if the user requests https://example.com/course/42/manage then this must instead be handled by the Moodle Router.

The Moodle Router is accessed from the file, r.php, which is located in the main Moodle directory.

How to configure the web server

Moodle supports a wide range of web servers. The guidance here is general in nature and the configuration examples may not apply exactly to your circumstances.

Configuring Apache2

This process requires root access. Apache2 can be configured to support the Moodle Router by specifying a FallbackResource in the Directory directive. If not already defined, also add the DirectoryIndex index.php directive directly above the FallbackResource directive to prevent HTTP 404 errors from occurring with the Moodle Router.

DocumentRoot /var/www/moodle/public
<Directory /var/www/moodle/public>
    AllowOverride None
    Require all granted
    DirectoryIndex index.php
    FallbackResource /r.php
</Directory>

The FallbackResource is relative to the DocumentRoot so if Moodle is in a sub-directory, the path will be relative to that root. The Require all granted directive allows unconditional access to authenticated users.

DocumentRoot /var/www/moodle/public
<Directory /var/www/moodle/public/moodle>
    AllowOverride None
    Require all granted
    DirectoryIndex index.php
    FallbackResource /moodle/r.php
</Directory>


Without Root Access

Another way to configure Apache2 is using .htaccess but this is not the recommended approach and not tested regularly by Moodle HQ.

In the 'public' directory, open (or create) the .htaccess file. Add the following line to the start of the file (it may also work at other places in that file).

FallbackResource /r.php

The FallbackResource directive sets a handler for any URL that doesn't map to anything in your filesystem. The handler, r.php, is already present in the main moodle directory.


Configuring Nginx

The nginx server supports the use of a try_files directive, which checks for existence of files in the specified order, using the first found file for processing.

location / {
    try_files $uri /r.php;
}

If your Moodle site is in a sub-directory, you will need to use a more specific location.

location /moodle/ {
  try_files $uri $uri/ /moodle/r.php;
}

If you host multiple Moodles then you may wish to use a case-sensitive regular expression match for the location:

location ~ ^/(?<sitepath>[^/]*)/ {
  try_files $uri $uri/ /$sitepath/r.php;
}

IIS

Note: The following instructions are untested. If you have knoweldge of IIS and can provide more accurate or up-to-date instructions, please do so.

Using the URL Rewriter module for IIS, you can create a Rewrite rule in your web.config file.

<rewrite>
    <rules>
        <rule name="Moodle" stopProcessing="true">
            <match url="^(.*)$" ignoreCase="false" />
            <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
            </conditions>
            <action type="Rewrite" url="r.php" appendQueryString="true" />
        </rule>
    </rules>
</rewrite>

Configuring Moodle

After successfully configuring the Router, you should inform Moodle that it is correctly configured by setting the following in your config.php

$CFG->routerconfigured = true;

To test the system, login to Moodle, open a course, and note the id number in the address bar, which is 42 in this example: https://moodle.example.com/course/view.php?id=42. Try entering the following in the address bar: https://moodle.example.com/my/course/42/manage. The "my" shouldn't have been in there, so this will generate a distinctive error page, like the following.

Typical error message when FallbackResource is working.

Remove the "my/" from the address and it should take you to the appropriate page.