Ubuntu 18.04 Bionic Graphite Guide

Ubuntu 18.04 Bionic Graphite Guide


This is a small guide how to install graphite on Ubuntu Bionic.


For the following steps it is suggested that you setup the following steps in the root account.
If you have to switch the user it is given in the steps.
Also the starting point is an completly fresh installed system, no tinkering beforehand.
It is hard enough to to keep the steps in a reproduceable way with all the actual changes happening with new operating system releases around and also security fixes.
So keep it easy for yourself if you have the possibility make a clean fresh install of the os when trying to apply those steps.

Initial Update

First things first after an fresh install update your needed entries in /etc/apt/sources.list
After that issue an initial update.

#> apt-get update -y

Install the needed packages

#> apt-get install python-dev libcairo2-dev libffi-dev build-essential python-pip python-sqlite libapache2-mod-wsgi -y#> apt-get install golang -y

Create beforehand the needed Web-Certificates

Because before we setup the Graphite-Web Site we might secure it with an ssl certificate.

We first create an folder for the certs.

#> mkdir -pv /etc/pki/tls/private
#> cd /etc/pki/tls/private

For the convenience of things i just name the created certificate ‘certificate’. Best practice would be to name it like your machine or company.

Let’s generate a keyfile with openssl you should adjust the bits as the last parameter to your needs for this example 2048 should be enough.

#> openssl genrsa -out certificate.key 2048

Next is that we create with that keyfile an csr (certificate signing request).

#> openssl req -new -key certificate.key -out certificate.csr -subj "/C=UK/ST=Somewhere1/L=Somewhere/O=Somewhere Company GmbH/OU=IT/CN=localhost.local/emailAddress=admin@somewhere.com"

Explanation of the -subj parameters:

Parameter Explanation
/C Country
/ST State
/L Location
/O Organization
/OU Organizational Unit
/CN Common Name
/emailAddress self explanatory

Now let’s create a crt file

openssl x509 -req -days 3650 -in certificate.csr -signkey certificate.key -out certificate.crt

We create also an .pem (privacy enhanced mail) file if your organization might need this as well so we have at least covered this as well.

#> cat certificate.key > certificate.pem
#> cat certificate.crt >> certificate.pem

If you have intermediate certificate files you would also add them to the .pem files. This is more or less an chained certificate file then.

#> cat intermediate.crt >> certificate.pem


The first component we install for the ‘graphite stack’ is go-carbon.
It is maintained more robust and easier to install than the ‘normal carbon’ which is mostly outdated in the distro packages.

The downloadable file is found [here] (https://github.com/lomik/go-carbon/releases/download/v0.14.0/go-carbon_0.14.0_amd64.deb).

Clickable [Website link] (https://github.com/lomik/go-carbon/)

#> wget https://github.com/lomik/go-carbon/releases/download/v0.14.0/go-carbon_0.14.0_amd64.deb

The installation is done with the dpkg command:

#> dpkg -i go-carbon_0.14.0_amd64.deb

When the installation is finished we adjust the following two files: go-carbon.conf and the storage-schemas.conf.
Both can be found at /etc/go-carbon.

#> vi go-carbon.conf

Inside the go-carbon.conf we adjust the following settings:

max-cpu = 4 (default) // should be adjusted to the capabilities that your machine can offer
data-dir = "/var/lib/graphite/whisper" // adjust the data-dir to your needs wsp files can be huge if they should keep a lot of history
write-strategy = "max" // to go easy on the cpu we would set this to "noop"
\[udp\] = ... // should be commented if not used in your environment
\[tcp\] = ... // is the prefered transport
listen = ":2003" // can be prefixed with the ip where it should listen to would look like this ""

Next up is the storage-schemas.conf:

pattern = .*
retentions = 60s:30d,1h:5y

This is the default storage pattern because this is the icinga community forum is take as an example the icinga2 storage pattern.

pattern = ^icinga\..*\.(max_check_attempts|reachable|current_attempt|execution_time|latency|state|state_type)
retentions = 5m:7d
pattern = ^icinga\.
retentions = 1m:2d,5m:10d,30m:90d,360m:4y

On how to calculate the expected file size of the created whisper files i mostly advise the users to take a look at the following to to estimate the file size which to expect.

[whisper file size calculator] (https://m30m.github.io/whisper-calculator/)

And finally we create the systemctl entry so the service gets started after a restart as well.

#> systemctl enable go-carbon // this can be extended with --now for immediate start of the service

Whisper and Graphite-Web

Now we move on the the rest of the ‘graphite stack’ here we go with the packages from the graphite-project.
First we need to make sure that the PYTHONPATH is the correct one during the upcoming pip install.
So you can do it like i did with setting the env variable in the commandline for the session (not restart safe) or adding it to the profile of the root or user account you need for your setup.

#> export PYTHONPATH="/opt/graphite/lib/:/opt/graphite/webapp/"

At last we can perform yet the pip install for whisper and the graphite-web.

#> pip install --no-binary=:all: https://github.com/graphite-project/whisper/tarball/1.1.5
#> pip install --no-binary=:all: https://github.com/graphite-project/graphite-web/tarball/1.1.5

Again we need to copy and adjust conf files:

#> cp /opt/graphite/webapp/graphite/local_settings.py.example /opt/graphite/webapp/graphite/local_settings.py
#> vi /opt/graphite/webapp/graphite/local_settings.py

In the local_settings.py there should the following adjustments be made:

TIME_ZONE = 'America/Los Angeles'
WHISPER_DIR = '/opt/graphite/storage/whisper'

Start with the SECRET_KEY, we don’t type something dull we create safe random one.
So let us generate one.

#> openssl rand -base64 32
#> gDvnYH48cgswnLljvFZ4+xMn6WqsUHh7MXf0sSpAqxQ=

We take that as a SECRET_KEY.

SECRET_KEY = 'gDvnYH48cgswnLljvFZ4+xMn6WqsUHh7MXf0sSpAqxQ='
ALLOWED_HOSTS = [ '*' ]  // here we adjust which other machines can access the graphite web
TIME_ZONE = 'America/Los Angeles' // time zone i think you know what to add here
WHISPER_DIR = '/var/lib/graphite/whisper' // In this case we have to point to where the whisper files are

Create the Whisper Directory and adjust Ownership

#> mkdir -pv /var/lib/graphite/whisper
#> chown -Rf carbon. /var/lib/graphite/whisper

Graphite Web WSGI Stuff

Same procedure as before we copy example to be useable.

#> cp /opt/graphite/conf/graphite.wsgi.example /opt/graphite/conf/graphite.wsgi

Graphite Website

Here comes the Apache2 stuff.

Starting point is the following directory.

#> cd /etc/apache2/sites-available/

now we create the following

#> vi graphite-web-ssl.conf

I give here an example which you can copy and paste but might need to adjust to your own needs.

# Enable virtualhosts, perhaps by adding this to your server's config somewhere,
# probably the main httpd.conf
# NameVirtualHost *:443
# This line also needs to be in your server's config.
# LoadModule wsgi_module modules/mod_wsgi.so
# You need to manually edit this file to fit your needs.
# This configuration assumes the default installation prefix
# of /opt/graphite/, if you installed graphite somewhere else
# you will need to change all the occurrences of /opt/graphite/
# in this file to your chosen install location.
<IfModule !wsgi_module.c>
    LoadModule wsgi_module modules/mod_wsgi.so
# XXX You need to set this up!
# Read http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGISocketPrefix
# For example, create a directory /var/run/wsgi and use that.
WSGISocketPrefix /var/run/apache2/wsgi
<VirtualHost *:443>
    # Base Configuration
    ServerName localhost.local
    DocumentRoot "/opt/graphite/webapp"
    # Log Configuration
    ErrorLog /opt/graphite/storage/log/webapp/error.log
    CustomLog /opt/graphite/storage/log/webapp/access.log common
    # SSL Configuration
    SSLEngine On
    SSLCertificateFile /etc/pki/tls/private/certificate.crt
    SSLCertificateKeyFile /etc/pki/tls/private/certificate.key
    SSLCertificateChainFile /etc/pki/tls/private/certificate.pem
    # Graphite Related Configuration
    # I've found that an equal number of processes & threads tends
    # to show the best performance for Graphite (ymmv).
    WSGIDaemonProcess graphite processes=5 threads=5 display-name='%{GROUP}' inactivity-timeout=120
    WSGIProcessGroup graphite
    WSGIApplicationGroup %{GLOBAL}
    WSGIImportScript /opt/graphite/conf/graphite.wsgi process-group=graphite application-group=%{GLOBAL}
    # XXX You will need to create this file! There is a graphite.wsgi.example
    # file in this directory that you can safely use, just copy it to graphite.wgsi
    WSGIScriptAlias / /opt/graphite/conf/graphite.wsgi
    # XXX To serve static files, either:
    # * Install the whitenoise Python package (pip install whitenoise)
    # * Collect static files in a directory by running:
    #     django-admin.py collectstatic --noinput --settings=graphite.settings
    #   And set an alias to serve static files with Apache:
    Alias /static/ /opt/graphite/static/
    # URL-prefixed install #
    # If using URL_PREFIX in local_settings for URL-prefixed install (that is not located at "/"))
    # your WSGIScriptAlias line should look like the following (e.g. URL_PREFX="/graphite"
    # WSGIScriptAlias /graphite /srv/graphite-web/conf/graphite.wsgi/graphite
    # Alias /graphite/static /opt/graphite/webapp/content
    #  <Location "/graphite/static/">
    #        SetHandler None
    # </Location>
    # XXX In order for the django admin site media to work you
    # must change @DJANGO_ROOT@ to be the path to your django
    # installation, which is probably something like:
    # /usr/lib/python2.6/site-packages/django
    Alias /media/ "@DJANGO_ROOT@/contrib/admin/media/"
    # The graphite.wsgi file has to be accessible by apache. It won't
    # be visible to clients because of the DocumentRoot though.
    <Directory /opt/graphite/conf/>
        <IfVersion < 2.4>
            Order deny,allow
            Allow from all
        <IfVersion >= 2.4>
            Require all granted
    <Directory /opt/graphite/static/>
        <IfVersion < 2.4>
            Order deny,allow
            Allow from all
        <IfVersion >= 2.4>
            Require all granted

The following step should be to verify the syntax with the following command:

#> apachectl -t

Create graphite db stuff

In this demo case i just rely on the sqlite which is used by default but none the less it needs a setup.
So this is how it’s done

#> PYTHONPATH=/opt/graphite/webapp django-admin.py migrate --settings=graphite.settings --run-syncdb

Also we might need to create a admin/root user for the graphite-web interface

#> PYTHONPATH=/opt/graphite/webapp django-admin.py createsuperuser --settings=graphite.settings

Static Web files

Graphite Web consists out of generated Files which need to be create.

#> PYTHONPATH=/opt/graphite/webapp django-admin.py collectstatic --noinput --settings=graphite.settings  

To give apache2 access to these files we perform the follwing step.

#> chown -R www-data. /opt/graphite

Finalizing Steps

Were almost there …
What is missing ? Some small hiccups which might need to be solved i did the following.

#> a2enmod ssl
#> a2enmod wsgi
#> a2ensite graphite-web-ssl.conf
#> systemctl enable apache2 --now
#> systemctl enable go-carbon --now

If you have something that sends performance data into graphite then you can see the creation of the whisper files in /var/lib/graphite/whisper

and of course in the webview as well.

hope this helped and if there are points to improve please let me know.
Like i mentioned before this is a small guide which will evolve into the next bigger blogpost maybe.




many thanks! worked also for debian buster :+1:

1 Like