Note: You are currently viewing documentation for Moodle 3.9. Up-to-date documentation for the latest stable version of Moodle may be available here: Nginx.

Nginx: Difference between revisions

From MoodleDocs
No edit summary
No edit summary
 
(21 intermediate revisions by 7 users not shown)
Line 1: Line 1:
{{Installing Moodle}}[[Nginx]] [engine x] is an HTTP and reverse proxy server, as well as a mail proxy server, written by Igor Sysoev. The nginx project started with a strong focus on high concurrency, high performance and low memory usage. It is licensed under the 2-clause BSD-like license and it runs on Linux, BSD variants, Mac OS X, Solaris, AIX, HP-UX, as well as on other *nix flavors. It also has a proof of concept port for Microsoft Windows.
{{Installing Moodle}}[[Nginx]] [engine x] is an HTTP and reverse proxy server, as well as a mail proxy server, written by Igor Sysoev. The nginx project started with a strong focus on high concurrency, high performance and low memory usage. It is licensed under the 2-clause BSD-like license and it runs on Linux, BSD variants, Mac OS X, Solaris, AIX, HP-UX, as well as on other *nix flavours. It also has a proof of concept port for Microsoft Windows.


''The following is community-contributed documentation on Nginx configuration. Amendmends and additions are welcome.''
''The following is community-contributed documentation on Nginx configuration. Amendments and additions are welcome.''


== Nginx configuration ==
== Nginx configuration ==


=== FastCGI ===
=== PHP-FPM ===
<pre>
 
fastcgi_param QUERY_STRING $query_string;
Nginx is usually configured to interface with PHP via [http://php.net/manual/en/install.fpm.php php-fpm]. This is both fast and robust.
fastcgi_param REQUEST_METHOD $request_method;
 
fastcgi_param CONTENT_TYPE $content_type;
PHP-FPM's default behaviour for pools is usually to restrict the execution of scripts to a specific extension, i.e. .php. You should ensure that this behaviour is configured within your particular package/distribution, e.g. for debian,
fastcgi_param CONTENT_LENGTH $content_length;


fastcgi_param SCRIPT_NAME $fastcgi_script_name;
'''/etc/php5/fpm/pool.d/www.conf'''
fastcgi_param REQUEST_URI $request_uri;
security.limit_extensions = .php
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;


fastcgi_param GATEWAY_INTERFACE CGI/1.1;
=== Nginx ===
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;


fastcgi_param REMOTE_ADDR $remote_addr;
Add the following 'slash arguments' compatible 'location' block to your vhosts 'server' in your nginx configuration (further explanation at '[[Using slash arguments]]').
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;


# PHP only, required if PHP was built with --enable-force-cgi-redirect
'''nginx.conf location:'''
fastcgi_param REDIRECT_STATUS 200;
<pre>
location ~ [^/]\.php(/|$) {
    fastcgi_split_path_info  ^(.+\.php)(/.+)$;
    fastcgi_index            index.php;
    fastcgi_pass            127.0.0.1:9000 (or your php-fpm socket);
    include                  fastcgi_params;
    fastcgi_param  PATH_INFO      $fastcgi_path_info;
    fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
</pre>
</pre>


=== Slasharguments ===
If the above does not work try the following:
Note: This was for CentOS 7.6 (1804), MariaDB 10.3, Nginx 1.15 and PHP 7.3.5
<pre>
location ~ ^(.+\.php)(.*)$ {
    root /usr/share/nginx/html/moodle/;
    fastcgi_split_path_info  ^(.+\.php)(.*)$;
    fastcgi_index            index.php;
    fastcgi_pass            127.0.0.1:9000;
    include /etc/nginx/mime.types;
    include                  fastcgi_params;
    fastcgi_param  PATH_INFO      $fastcgi_path_info;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
</pre>
 
 
If you find that this does not work (scripts, styles, and images not loading) '''and''' that there are <code>open() "..." failed (20: Not a directory)</code> lines appearing in your logs: Check whether there are any directives related to static content '''before''' this block and try moving them '''after''' this block.


The slasharguments setting is intended mostly for diagnostic purposes and we strongly recommend this setting should be always '''enabled'''.


If you disable this '''slasharguments''' setting, many Moodle features will not work properly, such as:
Another potential pitfall is the use of '''try_files'''. Many guides recommend configurations like <pre>try_files $fastcgi_script_name =404;</pre>. But if try_files is used, nginx deletes the content of the '''$fastcgi_path_info''' variable (this is [https://trac.nginx.org/nginx/ticket/321 intended behavior]). This causes '''PATH_INFO''' to also be empty, so slash arguments don't work.
* SCORM packages.
An alternative is the use of <pre>if(!-f $document_root$fastcgi_script_name) {return 404;}</pre> [https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/#connecting-nginx-to-php-fpm as recommended] by the nginx documentation, although the nginx documentation also recommends [https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/ not using if].
* Relative links in embedded pages.
* Add-ons and plugins.
* Images.


If you disable slasharguments setting and embedded images start to be displayed it means that the server is not properly configured.
==== Error pages ====
'''Please note that will not be possible to disable slasharguments settings on moodle 3.0, we recommend to check and configure slasharguments in your webserver.'''


Some users are experiencing issues with relative links on Ngix web server as reported on the forum discussion:
<pre>
[https://moodle.org/mod/forum/discuss.php?d=83445]
# This passes 404 pages to Moodle so they can be themed
error_page 404 /error/index.php;    error_page 403 =404 /error/index.php;
</pre>


Those issues can be easily fixed by adding the following configuration to the nginx.conf:
==== Hiding internal files ====
'''nginx.conf location:'''
<pre>
<pre>
location ~ \.php(.*)$ {
# Hide all dot files but allow "Well-Known URIs" as per RFC 5785
include fastcgi_params;
location ~ /\.(?!well-known).* {
fastcgi_index index.php;
    return 404;
if (!-e $request_filename) {
}
rewrite ^(.*\.php)(/)(.*)$ $1?file=/$3 last;
# This should be after the php fpm rule and very close to the last nginx ruleset.
# Don't allow direct access to various internal files. See MDL-69333
location ~ (/vendor/|/node_modules/|composer\.json|/readme|/README|readme\.txt|/upgrade\.txt|db/install\.xml|/fixtures/|/behat/|phpunit\.xml|\.lock|environment\.xml) {
    deny all;
    return 404;
}
}
fastcgi_param SCRIPT_FILENAME /var/moodle_www/html$fastcgi_script_name;
</pre>
fastcgi_pass 127.0.0.1:9000;
 
fastcgi_read_timeout 250s;
==== XSendfile aka X-Accel-Redirect ====
 
Setting Moodle and Nginx to use XSendfile functionality is a big win as it frees PHP from delivering files allowing Nginx to do what it does best, i.e. deliver files.
 
Enable xsendfile for Nginx in Moodles config.php, this is documented in the config-dist.php, a minimal configuration look like this,
<pre>
$CFG->xsendfile = 'X-Accel-Redirect';
$CFG->xsendfilealiases = array(
    '/dataroot/' => $CFG->dataroot
);
</pre>
Accompany this with a matching 'location' block in your nginx server configuration.
<pre>
location /dataroot/ {
    internal;
    alias &lt;full_moodledata_path&gt;; # ensure the path ends with /
}
}
</pre>
</pre>
The definition of 'internal' here is '''critical''' as it prevents client access to your dataroot.


== See also ==
== See also ==


* https://docs.moodle.org/dev/Install_Moodle_On_Ubuntu_with_Nginx/PHP-fpm
* Real <tt>PATH_INFO</tt> support:
* https://moodle.org/mod/forum/discuss.php?d=83445
** https://moodle.org/mod/forum/discuss.php?d=278916
** https://moodle.org/mod/forum/discuss.php?d=307388
* '''[Deprecated]''' Internal rewriting to the HTTP GET <tt>file</tt> parameter:
** https://moodle.org/mod/forum/discuss.php?d=83445


[[Category:Installation]]
[[Category:Installation]]


[[es:Nginx]]
[[es:Nginx]]
[[pt-br:Nginx]]

Latest revision as of 00:00, 1 June 2021

Nginx [engine x] is an HTTP and reverse proxy server, as well as a mail proxy server, written by Igor Sysoev. The nginx project started with a strong focus on high concurrency, high performance and low memory usage. It is licensed under the 2-clause BSD-like license and it runs on Linux, BSD variants, Mac OS X, Solaris, AIX, HP-UX, as well as on other *nix flavours. It also has a proof of concept port for Microsoft Windows.

The following is community-contributed documentation on Nginx configuration. Amendments and additions are welcome.

Nginx configuration

PHP-FPM

Nginx is usually configured to interface with PHP via php-fpm. This is both fast and robust.

PHP-FPM's default behaviour for pools is usually to restrict the execution of scripts to a specific extension, i.e. .php. You should ensure that this behaviour is configured within your particular package/distribution, e.g. for debian,

/etc/php5/fpm/pool.d/www.conf

security.limit_extensions = .php

Nginx

Add the following 'slash arguments' compatible 'location' block to your vhosts 'server' in your nginx configuration (further explanation at 'Using slash arguments').

nginx.conf location:

location ~ [^/]\.php(/|$) {
    fastcgi_split_path_info  ^(.+\.php)(/.+)$;
    fastcgi_index            index.php;
    fastcgi_pass             127.0.0.1:9000 (or your php-fpm socket);
    include                  fastcgi_params;
    fastcgi_param   PATH_INFO       $fastcgi_path_info;
    fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

If the above does not work try the following: Note: This was for CentOS 7.6 (1804), MariaDB 10.3, Nginx 1.15 and PHP 7.3.5

location ~ ^(.+\.php)(.*)$ {
    root /usr/share/nginx/html/moodle/;
    fastcgi_split_path_info  ^(.+\.php)(.*)$;
    fastcgi_index            index.php;
    fastcgi_pass             127.0.0.1:9000;
    include /etc/nginx/mime.types;
    include                  fastcgi_params;
    fastcgi_param   PATH_INFO       $fastcgi_path_info;
    fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
}


If you find that this does not work (scripts, styles, and images not loading) and that there are open() "..." failed (20: Not a directory) lines appearing in your logs: Check whether there are any directives related to static content before this block and try moving them after this block.


Another potential pitfall is the use of try_files. Many guides recommend configurations like

try_files $fastcgi_script_name =404;

. But if try_files is used, nginx deletes the content of the $fastcgi_path_info variable (this is intended behavior). This causes PATH_INFO to also be empty, so slash arguments don't work. An alternative is the use of

if(!-f $document_root$fastcgi_script_name) {return 404;}

as recommended by the nginx documentation, although the nginx documentation also recommends not using if.

Error pages

# This passes 404 pages to Moodle so they can be themed
error_page 404 /error/index.php;    error_page 403 =404 /error/index.php;

Hiding internal files

# Hide all dot files but allow "Well-Known URIs" as per RFC 5785
location ~ /\.(?!well-known).* {
    return 404;
}
 
# This should be after the php fpm rule and very close to the last nginx ruleset.
# Don't allow direct access to various internal files. See MDL-69333
location ~ (/vendor/|/node_modules/|composer\.json|/readme|/README|readme\.txt|/upgrade\.txt|db/install\.xml|/fixtures/|/behat/|phpunit\.xml|\.lock|environment\.xml) {
    deny all;
    return 404;
}

XSendfile aka X-Accel-Redirect

Setting Moodle and Nginx to use XSendfile functionality is a big win as it frees PHP from delivering files allowing Nginx to do what it does best, i.e. deliver files.

Enable xsendfile for Nginx in Moodles config.php, this is documented in the config-dist.php, a minimal configuration look like this,

$CFG->xsendfile = 'X-Accel-Redirect';
$CFG->xsendfilealiases = array(
    '/dataroot/' => $CFG->dataroot
);

Accompany this with a matching 'location' block in your nginx server configuration.

location /dataroot/ {
    internal;
    alias <full_moodledata_path>; # ensure the path ends with /
}

The definition of 'internal' here is critical as it prevents client access to your dataroot.

See also