How to Configure Munin for ea-nginx and Apache on cPanel/WHM

If you have ea-nginx installed on your cPanel server and you open Munin in WHM, you will notice something is wrong pretty quickly. The Apache graphs may be missing or showing no data, and there is no Nginx category at all. This is not a Munin bug — it is a configuration mismatch when adding the reverse proxy ea-nginx. This guide walks through fixing it completely, including the cPanel-specific quirks that generic Munin documentation does not cover.


What ea-nginx Changes and Why It Breaks Munin

On a standard cPanel server without ea-nginx, Apache listens directly on ports 80 and 443. Munin’s Apache plugins assume this and work without any configuration.

When you enable ea-nginx, Nginx becomes a reverse proxy and takes over ports 80 and 443. Apache gets pushed back to internal ports 81 and 444. Every visitor request hits Nginx first on port 80 or 443, and Nginx forwards it to Apache on port 81. From the outside nothing changes. Internally, everything does.

This breaks Munin in two ways:

  1. The Apache plugins default to polling port 80, which is now Nginx. They get back either wrong data or HTML they cannot parse, and produce nothing useful.
  2. By default, Munin’s Nginx plugins are not active. So Munin has no visibility into the reverse proxy layer handling all your traffic.

Both need to be fixed.


Important: cPanel’s Munin Is Not a Standard Install

Before touching anything, understand that Munin installed through WHM does has different paths that Linux and generic Munin guides describe.

The standard paths you find in most documentation do not exist here:

  • /usr/share/munin/plugins/ — does not exist
  • /usr/bin/munin-run — does not exist

The actual cPanel paths are:

  • Bundled plugins: /usr/local/cpanel/3rdparty/share/munin/plugins/
  • Active plugins (symlinks): /etc/munin/plugins/
  • Plugin configuration: /etc/munin/plugin-conf.d/
  • munin-cron binary: /usr/local/cpanel/3rdparty/bin/munin-cron
  • munin-node-configure: /usr/local/cpanel/3rdparty/bin/munin-node-configure

There is no munin-run in cPanel’s build.


Step 1 — Confirm the Port Layout

Before changing anything, verify that ea-nginx has actually moved Apache off ports 80 and 443:

ss -tlnp | grep -E ':(80|81|443|444) '

You should see Nginx owning 80 and 443, and Apache (httpd) on 81 and 444. If Apache still shows on port 80, ea-nginx is not fully enabled. Run /scripts/ea-nginx config --enable and restart both services before continuing. You can also verify Apache’s listening ports via WHM > Tweaks.


Step 2 — Fix the Apache Munin Plugins

Check What Is Already Symlinked

On a standard WHM server with Munin enabled, the three Apache plugins are usually already symlinked into the active directory:

ls /etc/munin/plugins/ | grep apache

You should see apache_accesses, apache_processes, and apache_volume. If any are missing, create the symlinks manually:

ln -s /usr/local/cpanel/3rdparty/share/munin/plugins/apache_accesses /etc/munin/plugins/apache_accessesln -s /usr/local/cpanel/3rdparty/share/munin/plugins/apache_processes /etc/munin/plugins/apache_processesln -s /usr/local/cpanel/3rdparty/share/munin/plugins/apache_volume /etc/munin/plugins/apache_volume

cPanel Uses a Non-Standard Status URL

This is the most important cPanel-specific detail for Apache monitoring. Standard Apache installations expose their status page at /server-status. cPanel’s Apache uses a different path:

/whm-server-status

If you configure the Munin plugins to hit /server-status they will 404. Always use /whm-server-status on cPanel.

Verify it is working on port 81 before touching any config:

curl "http://127.0.0.1:81/whm-server-status?auto"

The ?auto at the end is required. Without it Apache returns an HTML page instead of the plain key/value text that the Munin plugins can parse. A successful response looks like this:

Total Accesses: 84123Total kBytes: 1937482CPULoad: .031Uptime: 432001BusyWorkers: 4IdleWorkers: 14

If this returns a 403, check that the Location /whm-server-status block in /etc/apache2/conf/httpd.conf has Require local and that you are curling from localhost.

Create the Apache Plugin Config File

Open /etc/munin/plugin-conf.d/cpanel.conf and you will notice it has MySQL, diskstats, exim, and other sections — but no Apache section at all. Without one, the plugins default to port 80, which is now Nginx.

Do not edit cpanel.conf directly. cPanel can regenerate or overwrite it on updates. Create a separate file instead:

nano /etc/munin/plugin-conf.d/apache.conf

Add this content:

[apache_*]env.url http://127.0.0.1:%d/whm-server-status?autoenv.ports 81

The %d in the URL is replaced at runtime by each value in env.ports. The plugins will now poll Apache correctly on port 81.

Test the Apache Plugins

Since there is no munin-run, execute the plugin scripts directly:

/etc/munin/plugins/apache_accesses/etc/munin/plugins/apache_processes/etc/munin/plugins/apache_volume

Each should print numeric output with no error messages. If you see HTML or a connection error, the plugin is still hitting the wrong endpoint. Check env.url and env.ports and run the curl command again to confirm port 81 is responding.


Step 3 — Enable Nginx stub_status

Nginx does not expose any metrics by default. You have to explicitly enable the stub_status module at a specific URL. Once enabled, it returns a small plain-text block with live connection counts that the Munin plugins parse.

Finding the Right Place for the Config

ea-nginx on cPanel manages its Nginx configuration automatically. If you look at /etc/nginx/conf.d/ you will find cPanel-managed files you should not edit directly. However, there is a server-includes subdirectory that cPanel uses for location-level additions and does not overwrite:

ls /etc/nginx/conf.d/server-includes/

You will already see a file like cpanel-static-locations.conf in there. This is exactly where to put the stub_status location block.

Create a new file:

nano /etc/nginx/conf.d/server-includes/munin-nginx-status.conf

Add this content:

location /nginx_status {    stub_status on;    access_log  off;    allow       127.0.0.1;    deny        all;}

The allow/deny pair ensures this endpoint is only reachable from localhost. The access_log off line stops every 5-minute Munin poll from cluttering your access logs.

Why Not Port 8088 or a Separate Server Block?

You might see other guides suggest putting stub_status on a dedicated custom port. With cPanel’s ea-nginx setup this is unnecessary and adds complexity — an extra listening socket, potential firewall concerns, and deviation from cPanel’s config structure. Adding stub_status as a location inside the existing port 80 server block is the cleaner approach.

Test and Reload

Validate the config first, then reload using cPanel’s restart script:

nginx -t/scripts/restartsrv_nginx

Then test the endpoint:

curl http://127.0.0.1/nginx_status

A working response looks like this:

Active connections: 46server accepts handled requests 6964 6964 4734Reading: 0 Writing: 1 Waiting: 45

If you get a 404 here, the location block is not being included. Double-check that the file is in the correct server-includes directory and that nginx -t passes without errors.

What About Port 443?

You do not need a separate stub_status block for HTTPS. Nginx tracks all connections — including those arriving on port 443 — at the worker process level. The /nginx_status page on port 80 reflects totals across all ports. One endpoint covers both HTTP and HTTPS traffic.


Step 4 — Add and Configure the Nginx Munin Plugins

Confirm the Plugins Are Available

cPanel’s Munin ships with two Nginx plugins already bundled. Check they are there:

ls /usr/local/cpanel/3rdparty/share/munin/plugins/nginx*

You should see:

/usr/local/cpanel/3rdparty/share/munin/plugins/nginx_request/usr/local/cpanel/3rdparty/share/munin/plugins/nginx_status

nginx_request graphs requests per second. nginx_status graphs active connections and their states (reading, writing, waiting). Both are worth enabling.

Symlink the Plugins

ln -s /usr/local/cpanel/3rdparty/share/munin/plugins/nginx_request /etc/munin/plugins/nginx_requestln -s /usr/local/cpanel/3rdparty/share/munin/plugins/nginx_status /etc/munin/plugins/nginx_status

Create the Nginx Plugin Config

nano /etc/munin/plugin-conf.d/nginx.conf

Add this content:

[nginx_*]env.url http://127.0.0.1/nginx_statusenv.port 80

Test the Plugins

/etc/munin/plugins/nginx_request/etc/munin/plugins/nginx_status

Both should return numeric output immediately. If either returns an error or nothing, the stub_status endpoint is not reachable. Run curl http://127.0.0.1/nginx_status first — if that works, the plugins should work too.


Step 5 — Restart munin-node and Trigger a Collection

Restart munin-node to pick up all the new symlinks and config files. First find the exact service name on your server:

systemctl list-units | grep -i munin

Then restart it:

systemctl restart cpanel-munin-node

Rather than waiting up to 5 minutes for the cron job, trigger an immediate collection:

/usr/local/cpanel/3rdparty/bin/munin-cron

Then open WHM → cPanel → Munin. You should now see an nginx category in the list alongside apache, disk, mysql, and the others. The apache graphs should also now show real data from port 81.

Graphs may appear flat or empty for the first cycle — Munin needs at least two data points to draw a line. Wait about 10 minutes and refresh.


Quick Troubleshooting Reference

nginx category is missing in WHM Run /etc/munin/plugins/nginx_request directly. Any error output in the response will cause Munin to silently drop the category from the UI.

Plugin output is HTML instead of numbers The plugin is hitting the wrong URL. Check env.url and env.ports in your config file, and run curl on the endpoint manually to confirm it responds correctly.

curl /nginx_status returns 404 The stub_status location block is not being included. Confirm the file exists in server-includes/ and that nginx -t passes cleanly.

curl /nginx_status returns 403 The allow 127.0.0.1 directive is missing or in the wrong order. Make sure allow comes before deny all in the location block.

Apache plugins return connection refused or HTML They are still hitting port 80. Confirm /etc/munin/plugin-conf.d/apache.conf exists and contains env.ports 81.

curl /whm-server-status?auto returns 403 Check the Location /whm-server-status block in /etc/apache2/conf/httpd.conf for a Require local directive.

munin-run: No such file or directory cPanel’s Munin build does not ship munin-run. Run plugin scripts directly from /etc/munin/plugins/.

Graphs appear but are always empty Run /usr/local/cpanel/3rdparty/bin/munin-cron manually and wait 10 minutes.

Config changes disappear after a cPanel update You edited cpanel.conf directly. Always create separate files like apache.conf and nginx.conf in plugin-conf.d/ — cPanel does not touch those.


All Four Files at a Glance

Here is everything that needs to be in place for a complete working setup:

/etc/nginx/conf.d/server-includes/munin-nginx-status.conf

location /nginx_status {    stub_status on;    access_log  off;    allow       127.0.0.1;    deny        all;}

/etc/munin/plugin-conf.d/nginx.conf

[nginx_*]env.url http://127.0.0.1/nginx_statusenv.port 80

/etc/munin/plugin-conf.d/apache.conf

[apache_*]env.url http://127.0.0.1:%d/whm-server-status?autoenv.ports 81

Symlinks in /etc/munin/plugins/

nginx_request → /usr/local/cpanel/3rdparty/share/munin/plugins/nginx_requestnginx_status  → /usr/local/cpanel/3rdparty/share/munin/plugins/nginx_statusapache_*      → already present on a standard WHM + Munin install

No third-party packages. No edits to cPanel-managed files. No custom ports. Everything survives cPanel updates cleanly because it all lives in files and directories that cPanel does not touch.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *