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:
- 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.
- 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 apacheYou 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_volumecPanel 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-statusIf 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: 14If 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.confAdd this content:
[apache_*]env.url http://127.0.0.1:%d/whm-server-status?autoenv.ports 81The %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_volumeEach 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.confAdd 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_nginxThen test the endpoint:
curl http://127.0.0.1/nginx_statusA working response looks like this:
Active connections: 46server accepts handled requests 6964 6964 4734Reading: 0 Writing: 1 Waiting: 45If 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_statusnginx_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_statusCreate the Nginx Plugin Config
nano /etc/munin/plugin-conf.d/nginx.confAdd this content:
[nginx_*]env.url http://127.0.0.1/nginx_statusenv.port 80Test the Plugins
/etc/munin/plugins/nginx_request/etc/munin/plugins/nginx_statusBoth 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 muninThen restart it:
systemctl restart cpanel-munin-nodeRather than waiting up to 5 minutes for the cron job, trigger an immediate collection:
/usr/local/cpanel/3rdparty/bin/munin-cronThen 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 81Symlinks 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 installNo 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