Jump to content

ProcessWire on NGINX


jose

Recommended Posts

Here's the full vhost file for one of my PW sites that uses ProCache. (Note that I've changed the real domain to example.com, and the ProCache string to "ProCache-xxxxxxxxxxxxx".)

server {
  listen 80;
  listen [::]:80;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  {{ssl_certificate_key}}
  {{ssl_certificate}}
  server_name example.com;
  return 301 https://www.example.com$request_uri;
}

server {
  listen 8080;
  listen [::]:8080;
  server_name www.example.com www1.example.com;
  {{root}}
  index index.php index.html;

}

server {
  listen 80;
  listen [::]:80;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  {{ssl_certificate_key}}
  {{ssl_certificate}}
  server_name www.example.com www1.example.com;
  {{root}}
  index index.php index.html;

  {{nginx_access_log}}
  {{nginx_error_log}}

  if ($scheme != "https") {
    rewrite ^ https://$host$uri permanent;
  }

  location ~ /.well-known {
    auth_basic off;
    allow all;
  }
  
  {{settings}}


  location ~* ^.+\.(css|js|jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|woff2|eot|mp4|ogg|ogv|webm|webp|zip|swf|map)$ {
    add_header Access-Control-Allow-Origin "*";
    expires 48h;
    access_log off;
    try_files $uri $uri/ /index.php?it=$uri&$args;
  }
	
	
	# Block access to ProcessWire system files
	location ~ \.(inc|info|module|sh|sql)$ {
		deny all;
	}


	# Block access to protected assets directories
	location ~ ^/(site|site-[^/]+)/assets/(cache|logs|backups|sessions|config|install|tmp)($|/.*$) {
		deny all;
	}

	# Block acceess to the /site/install/ directory
	location ~ ^/(site|site-[^/]+)/install($|/.*$) {
		deny all;
	}

	# Block dirs in /site/assets/ dirs that start with a hyphen
	location ~ ^/(site|site-[^/]+)/assets.*/-.+/.* {
		deny all;
	}

	# Block access to /wire/config.php, /site/config.php, /site/config-dev.php, and /wire/index.config.php
	location ~ ^/(wire|site|site-[^/]+)/(config|index\.config|config-dev)\.php$ {
		deny all;
	}

	# Block access to any PHP-based files in /templates-admin/
	location ~ ^/(wire|site|site-[^/]+)/templates-admin($|/|/.*\.(php|html?|tpl|inc))$ {
		deny all;
	}

	# Block access to any PHP or markup files in /site/templates/
	location ~ ^/(site|site-[^/]+)/templates($|/|/.*\.(php|html?|tpl|inc))$ {
		deny all;
	}

	# Block access to any PHP files in /site/assets/
	location ~ ^/(site|site-[^/]+)/assets($|/|/.*\.php)$ {
		deny all;
	}

	# Block access to any PHP files in core or core module directories
	location ~ ^/wire/(core|modules)/.*\.(php|inc|tpl|module)$ {
		deny all;
	}

	# Block access to any PHP files in /site/modules/
	location ~ ^/(site|site-[^/]+)/modules/.*\.(php|inc|tpl|module)$ {
		deny all;
	}

	# Block access to any software identifying txt files
	location ~ ^/(COPYRIGHT|INSTALL|README|htaccess)\.(txt|md)$ {
		deny all;
	}
	
	# ProCache Rules

    set $cache_uri $request_uri;

	if ($request_method = POST) {
		set $cache_uri 'nocache';
	}
	
	if ($request_method = HX_REQUEST) {
		set $cache_uri 'nocache';
	}

	if ($http_cookie ~* "wires_challenge") {
		set $cache_uri 'nocache';
	}
	
	if ($http_cookie ~* "persist") {
		set $cache_uri 'nocache';
	}


	

	# -----------------------------------------------------------------------------------------------
	# This location processes all other requests. If the request is for a file or directory that
	# physically exists on the server, then load the file. Else give control to ProcessWire.
	# -----------------------------------------------------------------------------------------------

	location / {
		expires -1;
		try_files /site/assets/ProCache-xxxxxxxxxxxxx/$cache_uri/index.html $uri $uri/ /index.php?it=$uri&$args;
	}


  
 location ~ \.php$ {
    include fastcgi_params;
    fastcgi_intercept_errors on;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    try_files $uri =404;
    fastcgi_read_timeout 3600;
    fastcgi_send_timeout 3600;
    fastcgi_param HTTPS "on";
    fastcgi_param SERVER_PORT 443;
    fastcgi_pass 127.0.0.1:{{php_fpm_port}};
    fastcgi_param PHP_VALUE "{{php_settings}}";
  }

  if (-f $request_filename) {
    break;
  }


}

 Hope this helps.

  • Like 4
Link to comment
Share on other sites

  • 3 weeks later...

And another thing to mention / take care of. Just because ProcessWire seems to be running fine that doesn't mean that you are all done. For example what if one of the installed modules had a custom .htaccess in it's module folder that has some custom rules that are necessary to protect some files from direct access? As far as I understand nginx will not be able to read these instructions and you might be open to attacks, no?

I think it should at least be clearly mentioned in this thread that anybody trying to use non-apache webservers for running ProcessWire has to take care of this risk on his own and check every single module and every single update or is otherwise really highjacking one of ProcessWires main strengths: Security.

For me this seems like a very high risk to take and I'd really be interested in numbers of how much faster nginx is compared to apache so that one can decide whether it's really worth the risk and additional effort.

  • Like 3
Link to comment
Share on other sites

Just wondering, if access to PHP files other than index.php in the site root is blocked (e.g., via the PW default .htaccess in the root), wouldn't this suggest that any .htaccess rules in a module subdirectory (like abc.om/site/modules/Module-name/.htaccess) would not have any effect on the overall operation of your ProcessWire site in Apache?

Link to comment
Share on other sites

@bernhardIn this test, I didn't want to install benchmark tools, so I just used PHP (code below) with the following results:

test 1)
Elapsed Processwire Boot time Apache/2.4.62: 0.1405s
Page load time: 6.53 ms
Database query time: 0.5 ms
Memory used: 325.21 KB

Elapsed Processwire Boot time nginx/1.26.1: 0.1175s
Page load time: 4.68 ms
Database query time: 0.65 ms
Memory used: 256.13 KB

test 2)
Elapsed Processwire Boot time Apache/2.4.62: 0.2145s
Page load time: 6.42 ms
Database query time: 0.45 ms
Memory used: 325.21 KB

Elapsed Processwire Boot time nginx/1.26.1: 0.1512s
Page load time: 4.86 ms
Database query time: 0.64 ms
Memory used: 256.13 KB

test 3)
Elapsed Processwire Boot time Apache/2.4.62: 0.1809s
Page load time: 48.97 ms
Database query time: 0.7 ms
Memory used: 325.21 KB

Elapsed Processwire Boot time nginx/1.26.1: 0.0909s
Page load time: 4.65 ms
Database query time: 0.64 ms
Memory used: 256.13 KB

<?php
$home = $pages->get('/'); /** @var HomePage $home */

$start_time = microtime(true);
$start_memory = memory_get_usage();
$start_query_time = microtime(true);
$pages = $pages->find("template=basic-page");
$query_time = microtime(true) - $start_query_time;
?>

?><!DOCTYPE html>
<!-- STANDARD >main.php body-->

<?php
$end_time = microtime(true);
$page_load_time = $end_time - $start_time;
$end_memory = memory_get_usage();
$memory_used = $end_memory - $start_memory;
$elapsed = Debug::stopTimer($timer, 's');  // Debug::startTimer in index.php
?>
        <div>
            <p>Elapsed Processwire Boot time <?php echo $_SERVER['SERVER_SOFTWARE'] . ': ' . $elapsed ?><br>
            Page load time: <?php echo round($page_load_time * 1000, 2); ?> ms<br>
            Database query time: <?php echo round($query_time * 1000, 2); ?> ms<br>
            Memory used: <?php echo round($memory_used / 1024, 2); ?> KB</p>
        </div>
	</body>
</html>

Breakdown of results:
Elapsed ProcessWire Boot Time: NGINX consistently shows lower boot times, indicating it may handle PHP requests more efficiently than Apache in this test case.
Page Load Time: The page load time in the third test for Apache (48.97 ms) is an anomaly I can't explain. Caching? Network latency?
Database Query Time: Apache and NGINX have similar query times
Memory Used: Memory usage is relatively low, and the difference between the two servers is not substantial.

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...