A fork of JasonRivers' Docker Nagios image that pulls in fixes from the open pull requests on his repo, along with other updates and quality-of-life improvements.
Listed here to give the original authors credit for their work.
- #96 - Fix issue with Nagiosgraph source (fregge)
- #101 - Fixes to allow building on ARM aarch64 architecture (garethrandall)
- #110 - Update to Ubuntu 18.04 LTS (asimzeeshan)
- #112 - Add python3-nagiosplugin for plugins that need it (davralin)
- #116 - Update Nagios to 4.4.6 (mmerian)
- #120 - Add NSCA (mmerian)
- #130 - Add Perl encryption libraries (rehashedsalt)
- #132 - Add rsync (LutzLegu)
- #165 - Added libcrypt-x509-perl and libtext-glob-perl modules (Scott-Jones-COS)
Things that I have changed/updated/added to date:
- Updated the image to Ubuntu 26.04 LTS
- Updated Nagios Core, Nagios Plugins, NRPE, NCPA and NSCA to their latest releases
- Added NagiosTV
- Added
check_mysqlandcheck_mysql_query, keptcheck_radiusworking on Ubuntu 26.04, and fixedcheck_gamenot being built - Built multi-arch images (amd64 & arm64)
- Switched to a multi-stage build, cutting the image size by nearly 60%
- Removed the default web interface password: set your own, or a random one is generated on first start
- Switched stored passwords from unsalted SHA-1 to bcrypt
- Gave a custom
NAGIOSADMIN_USERfull admin access in the web interface - Applied
NAGIOS_TIMEZONEandNAGIOS_FQDNat startup instead of at build time - Fixed SMTP relay authentication
- Made the container shut down cleanly within a few seconds
- Hardened the image: binaries and web files are owned by root, and Apache no longer shows its version
- Pinned every upstream source to an exact version, with a workflow that refreshes the pins every other week
- Added CI that lints, smoke-tests and scans every image for vulnerabilities before publishing it (an image with a fixable critical vulnerability isn't published), with SBOM and provenance attestations attached
The changelog lists every change by release.
Nagios Core running on Ubuntu 26.04 LTS with NagiosGraph, NRPE, NCPA, NSCA and NagiosTV.
| Product | Version |
|---|---|
| Nagios Core | 4.5.14 |
| Nagios Plugins | 2.5 |
| NRPE | 4.2.0 |
| NCPA | 3.5.1 |
| NSCA | 2.10.3 |
| NagiosTV | 0.10.0 |
All of the standard Nagios Plugins are included, plus the extras listed under Extra Plugins.
Note
check_radius is the one exception: Nagios Plugins can't build it on Ubuntu 26.04, so the image includes Ubuntu's build of it from the sister project, Monitoring Plugins, instead. See Using check_radius to set it up.
- Nagios and NSCA:
/opt/nagios/etc - NagiosGraph:
/opt/nagiosgraph/etc - Your own plugins:
/opt/Custom-Nagios-Plugins(use this path in your command definitions)
The images are available on Docker Hub and the GitHub Container Registry:
docker pull tronyx/nagios
docker pull ghcr.io/tronyx/nagios| Branch | Image Tag | Notes |
|---|---|---|
| Master | latest, master, master-<nagios version> |
Stable. |
| Develop | develop, develop-<nagios version> |
My testing/development branch for updates. |
I occasionally create other branches for testing, such as for a new Ubuntu LTS release, but these two are the main ones.
To try it out with the example configuration:
docker run --name nagios -p 8080:80 tronyx/nagiosTip
Then open http://localhost:8080/nagios/ and log in as nagiosadmin, using the password from the container log (see Credentials).
To keep your configuration and data outside the container, mount host directories:
docker run --name nagios \
-v /path/to/nagios/etc:/opt/nagios/etc \
-v /path/to/nagios/var:/opt/nagios/var \
-v /path/to/custom-plugins:/opt/Custom-Nagios-Plugins \
-v /path/to/nagiosgraph/etc:/opt/nagiosgraph/etc \
-v /path/to/nagiosgraph/var:/opt/nagiosgraph/var \
-p 8080:80 tronyx/nagiosEmpty directories are filled with the default configuration on first start, and the Nagios and NagiosGraph directories are handed to the container's nagios user (UID/GID 5000) on every start.
A few more options:
- To use the GitHub image, replace
tronyx/nagioswithghcr.io/tronyx/nagios. - To accept passive check results from remote hosts via NSCA, also publish its port with
-p 5667:5667. - For best results, give the container access to both IPv4 and IPv6 networks.
The included docker-compose.yml uses named volumes by default, with a commented-out bind mount alternative and examples for setting the admin password:
docker compose up -d| Variable | Description |
|---|---|
MAIL_RELAY_HOST |
Postfix relay host for outgoing mail. Include the port if it isn't 25, e.g. smtp.example.com:587 |
MAIL_RELAY_USERNAME |
Username for the relay host (requires MAIL_RELAY_HOST). Setting it also forces TLS to the relay |
MAIL_RELAY_PASSWORD |
Password for the relay host |
MAIL_INET_PROTOCOLS |
Postfix's inet_protocols setting, e.g. ipv4 |
NAGIOS_FQDN |
The server's fully qualified domain name, used by Postfix and as Apache's ServerName (default nagios.example.com) |
NAGIOS_TIMEZONE |
Timezone (default UTC). Written to nagios.cfg on every start, so it overrides any use_timezone you set there |
NAGIOSADMIN_USER |
Web interface admin username (default nagiosadmin). Only used on first start |
NAGIOSADMIN_PASS |
Web interface admin password. Only used on first start, and has no default (see Credentials) |
NAGIOSADMIN_PASS_FILE |
Path to a file containing the admin password, such as a Docker secret. Takes precedence over NAGIOSADMIN_PASS |
Important
There's no default password. If you don't set one, a random password is generated on first start and printed in the container log.
On first start, the login for NAGIOSADMIN_USER (default nagiosadmin) gets its password from the first of these that's set:
- The file named by
NAGIOSADMIN_PASS_FILE NAGIOSADMIN_PASS- If neither is set, a random password is generated and printed once in the container log:
$ docker logs nagios 2>&1 | grep 'Generated password'
Generated password for nagiosadmin: ddUoZ0rcvn4qe6sbami72LGTVnk3vtWith Docker Compose, a secret keeps the password out of the container's environment, where docker inspect would show it:
services:
nagios:
environment:
NAGIOSADMIN_PASS_FILE: /run/secrets/nagiosadmin_pass
secrets:
- nagiosadmin_pass
secrets:
nagiosadmin_pass:
file: ./nagiosadmin_pass.txtNote
These settings are only read when /opt/nagios/etc/htpasswd.users doesn't exist yet, such as on a fresh volume. Changing them later has no effect, so existing installs keep their current password.
To change the password later (it prompts for the new one):
docker exec -it nagios htpasswd -B /opt/nagios/etc/htpasswd.users nagiosadminThis also upgrades a password set by an older version of the image to the stronger bcrypt format.
check_radius comes from Ubuntu's Monitoring Plugins package, built against radcli, because Nagios Plugins can't build it on Ubuntu 26.04. It takes the same options as before, but needs a radcli configuration listing your RADIUS servers. Copy the default one into your etc volume once:
docker exec nagios sh -c 'cp -r /etc/radcli /opt/nagios/etc/radcli && sed -i "s|/etc/radcli/|/opt/nagios/etc/radcli/|" /opt/nagios/etc/radcli/radiusclient.conf && chown -R nagios:nagios /opt/nagios/etc/radcli && chmod 600 /opt/nagios/etc/radcli/servers'Then add your servers and shared secrets to /opt/nagios/etc/radcli/servers, and pass -F /opt/nagios/etc/radcli/radiusclient.conf to check_radius.
Warning
The container serves plain HTTP on port 80, and the web interface uses Basic authentication, which sends your password with every request. If it's reachable from anywhere other than a trusted local network, put it behind a reverse proxy that handles TLS, such as Traefik, nginx, Caddy or SWAG.
When setting up the proxy:
- Proxy a whole hostname, e.g.
https://nagios.example.com/, not a sub-path. Nagios, NagiosGraph and NagiosTV use the absolute paths/nagios/,/cgi-bin/and/nagiostv/. - Set
NAGIOS_FQDNto that hostname. - If the proxy reaches the container over a Docker network, you don't need to publish port 80 on the host.
The image's Docker health check reports healthy when Apache is answering requests and Nagios is running. It doesn't log in, so it works whatever password you set.
| Name/Link | Description |
|---|---|
| Nagios NRPE | Remotely execute Nagios plugins on other Linux/Unix machines |
| Nagios NCPA | Cross-platform monitoring agent |
| Nagios NSCA | Integrate passive alerts and checks from remote machines and applications |
| NagiosGraph | Graphs performance data from your checks, shown as popups for hosts and services |
| JR-Nagios-Plugins | Custom plugins from Jason Rivers |
| WL-Nagios-Plugins | Custom plugins from William Leibzon |
| JE-Nagios-Plugins | Custom plugins from Justin Ellison |
| DF-Nagios-Plugins | Custom plugins from Dan Fruehauf (check_sql, check_jenkins, check_vpn) |
| check_mssql_collection | MSSQL database and server checks from Nagios Enterprises |
| check_nwc_health | Network component (switch, router, firewall) checks from Gerhard Lausser |
| check_apc.pl | APC UPS checks via SNMP |
| QStat | Game server status query tool, installed at /usr/local/bin/qstat and used by the check_game plugin |
| check-mqtt | MQTT broker checks from Jan-Piet Mens |
| NagiosTV | Monitor your Nagios server on a wall-mounted TV |
Every upstream source is pinned to an exact version: git repositories to a commit (the *_COMMIT build args), the Ubuntu base image to a digest (BASE_IMAGE), downloaded files to a SHA-256 checksum, and Python packages to a version and hash (requirements.txt). Tagged releases are also checked at build time, so the build fails if a tag has been moved.
- Updating pins: run scripts/update-pinned-checksums.sh, which needs
git,curlanddocker buildx. It updates the Dockerfile and summarises what changed; review the diff before committing. Theupdate-pinsworkflow runs it every other week and opens a pull request againstdevelop. - Bumping a component: change its
*_VERSIONbuild arg (e.g.NAGIOS_VERSION) in the Dockerfile, then run the script to update its commit and checksums. - Updating Python packages: change the versions in requirements.in, then regenerate requirements.txt with the uv command at the top of either file.
requirements.txtlists every package and dependency with its version and hashes, so it's also the place to check what's currently in the image. - Updating CI tools: buildx, BuildKit and Trivy (in
build.ymlandscan.yml) and hadolint, shellcheck and actionlint (inlint.yml) are pinned by hand, and the script doesn't update them. Bump them now and then. - Testing an image:
scripts/smoke-test.sh <image>starts the image and checks logins, the web interface, key plugins, file permissions and a clean shutdown. CI runs it on every build before anything is published. - Vulnerability scans: CI scans every image with Trivy and uploads the results to the repository's Security β Code scanning page. If it finds a critical vulnerability that has a fix available, the build fails and nothing is published. The fix is usually a newer Ubuntu package. The build installs the current packages and upgrades the ones that come with the base image, but that layer is cached, so put
[no-cache]in the commit message of your next push to rebuild everything from scratch. A new base image digest fromupdate-pinsalso rebuilds it. - Weekly rescans: the
scanworkflow rescans the publishedmasteranddevelopimages every Tuesday, so vulnerabilities disclosed after a build still show up. Its results replace the build's on the Code scanning page, and it fails (which emails you) if there's a fixable critical vulnerability.
Note
GitHub only runs scheduled and manually triggered workflows from the default branch (develop), so changes to update-pins and scan take effect once they're on develop. update-pins also needs "Allow GitHub Actions to create and approve pull requests" enabled under Settings β Actions β General and, if the repository restricts which actions can run, peter-evans/create-pull-request@* added to the allowed actions on the same page.