Feature Request - Clear Nginx Cache Button (and all the code done for you too)

So I've discovered that the nginx caching is really problematic and constantly results in old content being served through Wordpress, especially if other levels of caching are used. Even with caching turned off in the ZesleCP backend, nginx is still always caching and serving up cached copies (please fix so we can turn off if needed).

So I got to thinking that it'd be nice to have an option to press a button in any WP install and clear those cache folders (which must be done by root as no other users have access to delete those folders).

To do it safely, my concept was to have a script to clear the cache files which will be run as root, then have a node listening on a random port for a random url to trigger a javascript that'll execute the sh script.

So first I created a script to clear the nginx cache folders /etc/myfolder/ClearNginxCache.sh
Code:
#!/bin/bash
sudo rm -rf /var/cache/nginx/zeslecp_dynamic/*
sudo rm -rf /var/cache/nginx/zeslecp_static/*
sudo service nginx restart
echo "Nginx cache cleared successfully."

Next, in installed node.js using: yum install nodejs

Then I created a javascript for the listener at /etc/myfolder/NginxClearListner.js
Code:
var http = require('http');
var exec = require('child_process').exec;

http.createServer(function (req, res) {
    if (req.url === '/clear-nginx-cache') {
        exec('/bin/bash /etc/myfolder/ClearNginxCache.sh', function(error, stdout, stderr) {
            if (error) {
                console.error(`exec error: ${error}`);
                return;
            }
            console.log(`stdout: ${stdout}`);
            console.error(`stderr: ${stderr}`);
        });
    }
    res.end('OK');
}).listen(9999);

This creates a listner node waiting for someone to browse to /clear-nginx-cache on port 9999 (use a random port of your own).

Next I created the service to run the listener node by creating the file /etc/systemd/system/nginx-clear-cache.service
Code:
[Unit]
Description=Nginx Cache Clear Listener
After=network.target

[Service]
ExecStart=/usr/bin/node /etc/myfolder/NginxClearListner.js
Restart=always
User=root
Group=root
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=/etc/myfolder/

[Install]
WantedBy=multi-user.target

Then I enabled and installed as a service using:
yum enable nginx-clear-cache
yum install nginx-clear-cache

Finally I made a wordpress plugin by creating a folder in WP /plugins/nginx-clear and adding in the file nginx-clear.php
Code:
<?php
/**
 * Plugin Name: Clear Nginx Cache
 * Description: Clear Nginx Cache via external Node.js server.
 * Version: 1.0
 * Author: Jared Palmer
 */

function clear_nginx_cache_button($wp_admin_bar) {
    $args = array(
        'id' => 'clear_nginx_cache',
        'title' => 'Clear Nginx Cache',
        'href' => wp_nonce_url(admin_url('?clear_nginx_cache=true'), 'clear_nginx_cache'),
        'meta' => array('class' => 'clear-nginx-cache-button')
    );
    $wp_admin_bar->add_node($args);
}
add_action('admin_bar_menu', 'clear_nginx_cache_button', 999);

function clear_nginx_cache_action() {
    if(isset($_GET['clear_nginx_cache']) && check_admin_referer('clear_nginx_cache')) {
        // Ensure the user has the 'manage_options' capability
        if(current_user_can('manage_options')) {
            $response = wp_remote_get('http://localhost:9999/clear-nginx-cache');
            if (is_wp_error($response)) {
                wp_die('Failed to clear Nginx cache: ' . $response->get_error_message());
            } else {
                wp_redirect(admin_url());
                exit;
            }
        }
    }
}
add_action('admin_init', 'clear_nginx_cache_action');

And the final result:
1686707496194.png

A simple button that clears that cache by simply triggering a localhost http to a specific url on a specific port (changed from the ones I actually used on my site).

You could probably secure it up a bit more into ZesleCP, but I don't think there's too much risk of a random listener node on a random port listening for a random url that when triggered can only clear the nginx cache anyway.

Maybe you could build this into the system and add the clear button to the WP one click installer. Just a thought ;).
 

Attachments

  • 1686707463134.png
    1686707463134.png
    72.4 KB · Views: 1
Last edited:

admin

Administrator
Staff member
Thanks for sharing the detailed code sample, I will pass this to our development team and will try to add this to our future release.
 
So on further investigation, it looks like there's a Nginx fastcgi_cache_purge module along with WP helper plugin that can handle dynamically clearing just the modified cache files to make it play nice with Wordpress. Here's what I'm talking about: https://easyengine.io/wordpress-nginx/tutorials/single-site/fastcgi-cache-with-purging/

Any idea how I can add in fastcgi_cache_purge module without breaking Zesle? It looks like it's not actually using fastcgi but rather just default HTML cache, which is not ideal for Wordpress.
 
Last edited:

admin

Administrator
Staff member
Hi,

We will look into it and will try to prioritize it for the next release. Thanks for sharing all the technical details and reference links.

In the meantime, I will check with the development team to see if there is any workaround.

Thanks
 
Top