Nginx: Difference between revisions
(The guide had incorrect alias definition. I had to add a different alias definition of NGINX to it work correctly. This solves https://moodle.org/mod/forum/discuss.php?d=349925 and https://moodle.org/mod/forum/discuss.php?d=413492) |
|||
Line 2: | Line 2: | ||
''The following is community-contributed documentation on Nginx configuration. Amendments and additions are welcome.'' | ''The following is community-contributed documentation on Nginx configuration. Amendments and additions are welcome.'' | ||
== Nginx configuration == | == Nginx configuration == | ||
=== PHP-FPM === | === PHP-FPM === | ||
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. | 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. | ||
Line 13: | Line 10: | ||
'''/etc/php5/fpm/pool.d/www.conf''' | '''/etc/php5/fpm/pool.d/www.conf''' | ||
security.limit_extensions = .php | security.limit_extensions = .php | ||
=== Nginx === | === Nginx === | ||
Line 31: | Line 26: | ||
} | } | ||
</pre> | </pre> | ||
If the above does not work try the following: | 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 | Note: This was for CentOS 7.6 (1804), MariaDB 10.3, Nginx 1.15 and PHP 7.3.5 | ||
Line 53: | Line 47: | ||
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. | 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. | ||
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]. | 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]. | ||
==== Error pages ==== | ==== Error pages ==== | ||
<pre> | <pre> | ||
# This passes 404 pages to Moodle so they can be themed | # This passes 404 pages to Moodle so they can be themed | ||
error_page 404 /error/index.php; error_page 403 =404 /error/index.php; | error_page 404 /error/index.php; error_page 403 =404 /error/index.php; | ||
</pre> | </pre> | ||
==== Hiding internal files ==== | ==== Hiding internal files ==== | ||
<pre> | <pre> | ||
# Hide all dot files but allow "Well-Known URIs" as per RFC 5785 | # Hide all dot files but allow "Well-Known URIs" as per RFC 5785 | ||
Line 79: | Line 69: | ||
==== XSendfile aka X-Accel-Redirect ==== | ==== 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. | 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. | ||
Line 91: | Line 80: | ||
Accompany this with a matching 'location' block in your nginx server configuration. | Accompany this with a matching 'location' block in your nginx server configuration. | ||
<pre> | <pre> | ||
location /dataroot/ { | location ~ ^/dataroot/(.*)$ { | ||
# The definition of 'internal' here is CRITICAL as it prevents client access to your dataroot. | |||
internal; | internal; | ||
alias | alias <full_moodledata_path>/$1; # ensure the path ends with '/$1' | ||
} | } | ||
</pre> | </pre> | ||
The definition of 'internal' here is '''critical''' as it prevents client access to your dataroot. | The definition of 'internal' here is '''critical''' as it prevents client access to your dataroot. | ||
== See also == | == See also == | ||
* Real <tt>PATH_INFO</tt> support: | * Real <tt>PATH_INFO</tt> support: | ||
** https://moodle.org/mod/forum/discuss.php?d=278916 | ** https://moodle.org/mod/forum/discuss.php?d=278916 | ||
Line 105: | Line 94: | ||
* '''[Deprecated]''' Internal rewriting to the HTTP GET <tt>file</tt> parameter: | * '''[Deprecated]''' Internal rewriting to the HTTP GET <tt>file</tt> parameter: | ||
** https://moodle.org/mod/forum/discuss.php?d=83445 | ** https://moodle.org/mod/forum/discuss.php?d=83445 | ||
[[Category:Installation]] | [[Category:Installation]] | ||
[[es:Nginx]] | [[es:Nginx]] | ||
[[pt-br:Nginx]] | [[pt-br:Nginx]] |
Revision as of 04:23, 29 August 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/(.*)$ { # The definition of 'internal' here is CRITICAL as it prevents client access to your dataroot. internal; alias <full_moodledata_path>/$1; # ensure the path ends with '/$1' }
The definition of 'internal' here is critical as it prevents client access to your dataroot.
See also
- Real PATH_INFO support:
- [Deprecated] Internal rewriting to the HTTP GET file parameter: