0

I run Nginx and PHP-FPM. Nginx runs under www-data and PHP-FPM runs as a separate user for each website. I use Nginx FASTCGI Caching and use the Nginx Helper plugin for WordPress. Unfortunately due to the difference in user we can't use the "Purge All" function in the plugin as the php user doesn't have access to the cache.

Changing permissions isn't an option due to security.

What I want to do is use a different PHP-FPM Pool if the below argument exists in the URL.

nginx_helper_urls=all 

My current NGinx Config is below:

 upstream examplebackend { server unix:/var/run/php-fcgi-example.sock; } upstream cachedeletebackend { server unix:/var/run/php-fcgi-cachedelete.sock; } server { listen 80 default; server_name www.example.com; return 301 https://www.example.com$request_uri; } server { listen 80; server_name example.com; return 301 https://www.example.com$request_uri; } server { listen 443 ssl; server_name example.com; return 301 https://www.example.com$request_uri; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; } server { listen 443 ssl; ssl_protocols TLSv1.2 TLSv1.3; server_name www.example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; access_log /home/examplecom/logs/example.com.access.log; error_log /home/examplecom/logs/example.com.error.log; root /home/examplecom/public_html; index index.php; set $skip_cache 0; # POST requests and urls with a query string should always go to PHP if ($request_method = POST) { set $skip_cache 1; } if ($query_string != "") { set $skip_cache 1; } # Don't cache uris containing the following segments if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") { set $skip_cache 1; } # Don't use the cache for logged in users or recent commenters if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") { set $skip_cache 1; } location / { try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { try_files $uri =404; include fastcgi_params; if ( $args ~ nginx_helper_urls=all ) { fastcgi_pass cachedeletebackend; } fastcgi_pass examplebackend; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; fastcgi_cache WORDPRESS; fastcgi_cache_valid 60m; } location ~ /purge(/.*) { fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1"; } location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { access_log off; log_not_found off; expires max; } location = /robots.txt { access_log off; log_not_found off; } location ~ /\. { deny all; access_log off; log_not_found off; } } 

Not sure where I am going wrong or if it is even possible. Thanks

1
  • 1
    What happens when you try to call this URL? Commented Feb 1, 2021 at 22:05

1 Answer 1

3

This likely happens because If is evil.

In nginx, most of the if statements should be implemented with map feature instead.

In your case, first define the map in http level:

map $arg_nginx_helper_urls $backend { all cachedeletebackend; default examplebackend; } 

Then, in PHP location block use:

location ~ \.php$ { try_files $uri =404; include fastcgi_params; fastcgi_pass $backend; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; fastcgi_cache WORDPRESS; fastcgi_cache_valid 60m; } 

The map will assign a value to $backend variable depending on query argument nginx_helper_urls value. By default, examplebackend is used. If the argument value is all, then cachedeletebackend is assigned to the variable.

2
  • This works perfectly on my current server which does only have one website. If I am to use this on my server with multiple sites with multiple different backends per site plus the cachedeletebackend. Where abouts in the config should I place the code to ensure its in the correct location. Would above the server section in each virtualconf file be adaquate? Commented Feb 2, 2021 at 1:20
  • You would configure upstream examplebackend and upstream cachedeletebackend accordingly for each of your virtual hosts. In Debian systems, you can put the map section into conf.d/cachemap.conf for example and it will work from there. Commented Feb 2, 2021 at 7:04

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.