Setup Munin on CentOS 7 with nginx

Munin provides web interface showing graphs about your server's load average, memory usage, CPU usage, MySQL throughput, eth0 traffic, etc. Although it lets you monitor more than one server, this article will discuss the monitoring of the system where it is installed. The following steps are tested running on my Linode server running Centos 7 64-bit. It is assumed that nginx is already installed in your system. If not, please follow this guide.

  1. Munin is available in EPEL repository. Lets first install EPEL repository:

          
    rpm -Uvh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm
    yum update
        
      
  2. Install Munin:

          
    yum install munin munin-node
          
        
  3. Create the system startup symlink for Munin and start it:

          
    systemctl enable munin-node
    systemctl start munin-node
        
      
  4. Create your custom Munin configuration file:

          
    vi /etc/munin/conf.d/00-munincustom.conf
          
        

    ... write the script below:

          
    graph_strategy cgi
    html_strategy cgi
          
        

    These config options enables to generate graphs and HTML dynamically. You can learn more about Munin's configuration options here.

  5. In Munin version 2.1.x and higher, it has munin-httpd which replaces the use of FastCGI. As of this writing the Munin binary package version available for CentOS 7 is 2.0.25 so we will have to use FastCGI in this case. Nginx does not automatically spawn FCGI-process, we need to install the spawn-fcgi and fcgiwrap first (the fcgiwrap needs to be compiled):

          
    yum install spawn-fcgi fcgi-devel autoconf automake gcc
          
        

    Compile fcgiwrap:

          
    cd /usr/src/
    wget http://github.com/gnosek/fcgiwrap/tarball/master -O fcgiwrap.tar.gz
    tar zxvf fcgiwrap.tar.gz
    rm -rf fcgiwrap.tar.gz
    cd gnosek-fcgiwrap-*
    autoreconf -i
    ./configure
    make
    make install
          
        
  6. Create the init.d script to spawn munin-cgi-html on system boot:

          
    vi /etc/init.d/spawn-fcgi-munin-html
          
        

    ... write the script below:

          
    #!/bin/sh
    #
    # spawn-fcgi-munin-html   Start and stop FastCGI Munin HTML processes
    #
    # chkconfig:   - 80 20
    # description: Spawn FastCGI scripts to be used by web servers
    
    ### BEGIN INIT INFO
    # Provides:
    # Required-Start: $local_fs $network $syslog $remote_fs $named
    # Required-Stop:
    # Should-Start:
    # Should-Stop:
    # Default-Start:
    # Default-Stop: 0 1 2 3 4 5 6
    # Short-Description: Start and stop FastCGI processes
    # Description:       Spawn FastCGI scripts to be used by web servers
    ### END INIT INFO
    
    # Source function library.
    . /etc/rc.d/init.d/functions
    
    exec="/usr/bin/spawn-fcgi"
    prog="spawn-fcgi-munin-html"
    config="/etc/sysconfig/spawn-fcgi-munin-html"
    
    [ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
    
    lockfile=/var/lock/subsys/$prog
    
    start() {
        [ -x $exec ] || exit 5
        [ -f $config ] || exit 6
        echo -n $"Starting $prog: "
        # Just in case this is left over with wrong ownership
        [ -n "${FCGI_SOCKET}" -a -S "${FCGI_SOCKET}" ] && rm -f ${FCGI_SOCKET}
        daemon "$exec $OPTIONS >/dev/null"
        retval=$?
        echo
        [ $retval -eq 0 ] && touch $lockfile
        return $retval
    }
    
    stop() {
        echo -n $"Stopping $prog: "
        killproc -p $PID_FILE
        # Remove the socket in order to never leave it with wrong ownership
        [ -n "${FCGI_SOCKET}" -a -S "${FCGI_SOCKET}" ] && rm -f ${FCGI_SOCKET}
        retval=$?
        echo
        [ $retval -eq 0 ] && rm -f $lockfile
        return $retval
    }
    
    restart() {
        stop
        start
    }
    
    reload() {
        restart
    }
    
    force_reload() {
        restart
    }
    
    rh_status() {
        # run checks to determine if the service is running or use generic status
        status $prog
    }
    
    rh_status_q() {
        rh_status &>/dev/null
    }
    
    
    case "$1" in
        start)
            #rh_status_q && exit 0
            $1
            ;;
        stop)
            #rh_status_q || exit 0
            $1
            ;;
        restart)
            $1
            ;;
        reload)
            #rh_status_q || exit 7
            $1
            ;;
        force-reload)
            force_reload
            ;;
        status)
            rh_status
            ;;
        condrestart|try-restart)
            rh_status_q || exit 0
            restart
            ;;
        *)
            echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
            exit 2
    esac
    exit $?
          
        

    Make it executable and activate it to start automatically during the system boot:

          
    chmod +x /etc/init.d/spawn-fcgi-munin-html
    chkconfig --levels 235 spawn-fcgi-munin-html on
          
        

    Create its configuration file script:

          
    vi /etc/sysconfig/spawn-fcgi-munin-html
          
        

    ... write the script below:

          
    # You must set some working options before the "spawn-fcgi" service will work.
    # If SOCKET points to a file, then this file is cleaned up by the init script.
    #
    # See spawn-fcgi(1) for all possible options.
    NAME=fcgi-munin-html
    PID_FILE=/run/munin/$NAME.pid
    FCGI_SOCKET=/run/munin/$NAME.sock
    FCGI_PROGRAM=/usr/local/sbin/fcgiwrap
    FCGI_USER=nginx
    FCGI_GROUP=munin
    FCGI_WORKERS=1
    FCGI_EXTRA_OPTIONS="-M 0700"
    OPTIONS="-u $FCGI_USER -g $FCGI_GROUP -s $FCGI_SOCKET -S $FCGI_EXTRA_OPTIONS -F $FCGI_WORKERS -P $PID_FILE -- $FCGI_PROGRAM"
          
        

    Start it:

          
    service spawn-fcgi-munin-graph start
          
        
  7. And create init.d script for munin-cgi-graph as well:

          
    vi /etc/init.d/spawn-fcgi-munin-graph
          
        

    ... write the script below:

          
    #!/bin/sh
    #
    # spawn-fcgi-munin-graph   Start and stop FastCGI Munin graph processes
    #
    # chkconfig:   - 80 20
    # description: Spawn FastCGI scripts to be used by web servers
    
    ### BEGIN INIT INFO
    # Provides:
    # Required-Start: $local_fs $network $syslog $remote_fs $named
    # Required-Stop:
    # Should-Start:
    # Should-Stop:
    # Default-Start:
    # Default-Stop: 0 1 2 3 4 5 6
    # Short-Description: Start and stop FastCGI processes
    # Description:       Spawn FastCGI scripts to be used by web servers
    ### END INIT INFO
    
    # Source function library.
    . /etc/rc.d/init.d/functions
    
    exec="/usr/bin/spawn-fcgi"
    prog="spawn-fcgi-munin-graph"
    config="/etc/sysconfig/spawn-fcgi-munin-graph"
    
    [ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
    
    lockfile=/var/lock/subsys/$prog
    
    start() {
        [ -x $exec ] || exit 5
        [ -f $config ] || exit 6
        echo -n $"Starting $prog: "
        # Just in case this is left over with wrong ownership
        [ -n "${FCGI_SOCKET}" -a -S "${FCGI_SOCKET}" ] && rm -f ${FCGI_SOCKET}
        daemon "$exec $OPTIONS >/dev/null"
        retval=$?
        echo
        [ $retval -eq 0 ] && touch $lockfile
        return $retval
    }
    
    stop() {
        echo -n $"Stopping $prog: "
        killproc -p $PID_FILE
        # Remove the socket in order to never leave it with wrong ownership
        [ -n "${FCGI_SOCKET}" -a -S "${FCGI_SOCKET}" ] && rm -f ${FCGI_SOCKET}
        retval=$?
        echo
        [ $retval -eq 0 ] && rm -f $lockfile
        return $retval
    }
    
    restart() {
        stop
        start
    }
    
    reload() {
        restart
    }
    
    force_reload() {
        restart
    }
    
    rh_status() {
        # run checks to determine if the service is running or use generic status
        status $prog
    }
    
    rh_status_q() {
        rh_status &>/dev/null
    }
    
    
    case "$1" in
        start)
            #rh_status_q && exit 0
            $1
            ;;
        stop)
            #rh_status_q || exit 0
            $1
            ;;
        restart)
            $1
            ;;
        reload)
            #rh_status_q || exit 7
            $1
            ;;
        force-reload)
            force_reload
            ;;
        status)
            rh_status
            ;;
        condrestart|try-restart)
            rh_status_q || exit 0
            restart
            ;;
        *)
            echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
            exit 2
    esac
    exit $?
          
        

    Make it executable and activate it to start automatically during the system boot:

          
    chmod +x /etc/init.d/spawn-fcgi-munin-graph
    chkconfig --levels 235 spawn-fcgi-munin-graph on
          
        

    Create its configuration file script:

          
    vi /etc/sysconfig/spawn-fcgi-munin-graph
          
        

    ... write the script below:

          
    # You must set some working options before the "spawn-fcgi" service will work.
    # If SOCKET points to a file, then this file is cleaned up by the init script.
    #
    # See spawn-fcgi(1) for all possible options.
    NAME=fcgi-munin-graph
    PID_FILE=/run/munin/$NAME.pid
    FCGI_SOCKET=/run/munin/$NAME.sock
    FCGI_PROGRAM=/usr/local/sbin/fcgiwrap
    FCGI_USER=nginx
    FCGI_GROUP=munin
    FCGI_WORKERS=2
    FCGI_EXTRA_OPTIONS="-M 0700"
    OPTIONS="-u $FCGI_USER -g $FCGI_GROUP -s $FCGI_SOCKET -S $FCGI_EXTRA_OPTIONS -F $FCGI_WORKERS -P $PID_FILE -- $FCGI_PROGRAM"
          
        

    Start it:

          
    service spawn-fcgi-munin-graph start
          
        
  8. Create a domain for Munin, in this guide lets use munin.yoursite.com. Go to DNS manager and add munin as A record for yoursite.com

  9. Now, lets create nginx configuration for munin.yoursite.com:

          
    vi /etc/nginx/sites-available/admin/munin.yoursite.com.conf
          
        

    ... and have the following codes as its content:

          
    server {
      listen XXX.XXX.XXX.XXX:80; # IPv4
      listen [XXXX:XXXX::XXXX:XXXX:XXXX:XXXX]:80 ipv6only=on; # IPv6
      server_name munin.yoursite.com;
      
      ## Logs
      log_not_found off;
      error_log /var/log/virtualmin/munin.tuwid.com_nginx_error_log error;
      access_log off;
    
      location / {
        fastcgi_split_path_info ^(/)(.*);
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME /var/www/html/munin/cgi/munin-cgi-html;
        include fastcgi_params;
        fastcgi_pass unix:/var/run/munin/fcgi-munin-html.sock;
        auth_basic "Restricted";
        auth_basic_user_file /etc/nginx/key/.htpasswd-users;
    
        # Serve static files
        location /static/ {
          alias /etc/munin/static/;
          expires 30d;
        }
    
        # Munin CGI graph
        location ^~ /munin-cgi/munin-cgi-graph/ {
          access_log off;
          fastcgi_split_path_info ^(/munin-cgi/munin-cgi-graph)(.*);
          fastcgi_param PATH_INFO $fastcgi_path_info;
          fastcgi_param SCRIPT_FILENAME /var/www/html/munin/cgi/munin-cgi-graph;
          include fastcgi_params;
          fastcgi_pass unix:/var/run/munin/fcgi-munin-graph.sock;
    
          # Bypass cache.
          fastcgi_cache_bypass 0;
          fastcgi_no_cache 0;
          expires epoch;
        }
      }
    }
          
        

    Note: Change the XXX.XXX.XXX.XXX and XXXX:XXXX::XXXX:XXXX:XXXX:XXX with your server's IPv4 and IPv6 addresses respectively.

  10. Create symbolic link for munin.yoursite.com.conf in /etc/nginx/sites-enabled/ to enable this configuration:

          
    ln -s /etc/nginx/sites-available/admin/munin.yoursite.com.conf /etc/nginx/sites-enabled/munin.yoursite.com.conf
          
        
  11. Add password protection to munin.yoursite.com:

          
    htpasswd /etc/nginx/key/.htpasswd-users admin
          
        

    This command will prompt password for the new user with the name admin.

  12. Restart nginx:

          
    systemctl restart nginx
          
        
  13. Setup logrotate for munin-cgi-html, munin-cgi-graph and nginx munin error logs:

          
    vi /etc/logrotate.d/munin-web
        
      

    ... write the script below:

          
    /var/log/munin/munin-cgi-html.log /var/log/munin/munin-cgi-graph.log /var/log/munin/munin-nginx-html-error.log {
      daily
      missingok
      rotate 7
      compress
      notifempty
      create 640 munin munin
      su munin munin
    }
          
        
  14. Your Munin can now be accessed at http://munin.yoursite.com:

    Munin web interface

    If something went wrong, these log files should give hint on your debugging:

          
    /var/log/munin/munin-cgi-html.log
    /var/log/munin/munin-cgi-graph.log
    /var/log/munin/munin-nginx-html-error.log
          
        
  15. To install Munin plugins check this article: Setup Munin plugins on CentOS 7.

  16. (Optional) If you are not satisfied with the Munin's theme, you may want to check this article: Setup alternative Twitter Bootstrap based Munin template.

Comments

Why do you need spawn-fcgi if systemd may do it by itself?

You just need munin-cgi-graph.socket
[Unit]
Description=Munin socket

[Socket]
ListenStream=/run/munin/munin-cgi-graph.sock
Accept=false

[Install]
WantedBy=sockets.target

And munin-cgi-graph.service
[Unit]
Description=Munin cgi graphics
After=network.target
Requires=munin-cgi-graph.socket

[Service]
ExecStart=/var/www/cgi-bin/munin-cgi-graph
User=munin
Type=simple
Group=nginx
StandardInput=socket

[Install]
WantedBy=multi-user.target

Thats is all. Systemd creates socket and provides to STDIN of munin script just like FastCGI should do (StandardInput=socket).

It works.

Can be simpler in one script
wget -O /etc/init.d/munin-fcgi https://pastebin.com/raw/NJxDaZ7U
chown root:root /etc/init.d/munin-fcgi
chmod 755 /etc/init.d/munin-fcgi
chkconfig --levels 235 munin-fcgi on
/etc/init.d/munin-fcgi start

see https://pastebin.com/raw/NJxDaZ7U

#sudo yum install munin munin-nginx
#sudo systemctl enable munin-fcgi-graph.service
#sudo systemctl enable munin-fcgi-html.service

Then check if /etc/nginx/conf.d/munin.conf suites your needs.

Since I couldn't comment on the blog post for the installation instructions I followed - located here https://denis.no/2016/07/munin-2-0-on-centos7-with-nginx-and-fastcgi/ - but since that author references this post, I'm going to list how I got munin working on my CentOS v7 system. NOTE - I don't think that I'm using cgi-html

1) Edit /etc/cron.d/munin and un-comment the line with munin-cron
2) Correct paths for the UNIX sockets in nginx.conf to:
fastcgi_param SCRIPT_FILENAME /var/www/html/munin/cgi/munin-cgi-html;
fastcgi_pass unix:/run/munin/munin-cgi-html.sock;
fastcgi_param SCRIPT_FILENAME /var/www/html/munin/cgi/munin-cgi-graph;
fastcgi_pass unix:/run/munin/munin-cgi-graph.sock;

Hope this helps some one - I was just trying to get munin working after re-installing to CentOS v7; not trying to get an optimal nginx/munin configuration

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.