The Essential Guide to Grafana Docker Monitoring

Published:17 May 2022 - 10 min. read

Azure Cloud Labs: these FREE, on‑demand Azure Cloud Labs will get you into a real‑world environment and account, walking you through step‑by‑step how to best protect, secure, and recover Azure data.

Prometheus and Grafana are great tools for both metric data collection and visualization. But like any other tool, both have their strengths and weaknesses. To get the most out of your metric data, you’ll have both Prometheus and Grafana Docker Monitoring tools work in tandem.

In this tutorial, you’ll learn how to monitor your Docker instance and collect time-series data for analysis with Grafana Docker monitoring.

Read on and take your workflow to a whole new level!

Prerequisites

This tutorial comprises hands-on demonstrations. To follow along, make sure to have the following:

  • An Ubuntu 20.04 machine – This tutorial uses the Ubuntu 20.04 machine as the Docker host.
  • Configure your firewall rules to allow traffic on ports 80, 443, and 9323 for HTTP and HTTPS connection and your Docker metrics.
  • A user with sudo privileges.
  • A registered domain name that points to your server’s IP address – This tutorial uses NGINX as a reverse proxy to route traffic to Grafana through the domain name to Grafana running in Docker.

Configuring Docker for Grafana

Before viewing all sorts of Docker metrics on Grafana, you must configure Docker first to expose its metrics via an HTTP endpoint. These Docker metrics can be states of containers available on the Docker host and resource utilization of each container.

To expose the Docker metrics, you’ll create a .json file to configure the Docker daemon:

1. Open the daemon.json file in the /etc/docker/ directory using your preferred text editor and add the following code. The code below configures the Docker daemon to expose the Docker metrics at 0.0.0.0 via port 9323 (endpoint: http://0.0.0.0:9323).

{
	"metrics-addr" : "0.0.0.0:9323",
	"experimental" : true
}

2. Run the following command to restart the docker service for the changes you made on the daemon.json file to take effect. This command doesn’t provide output, but you’ll check the Docker service’s status in the following step.

sudo service docker restart

3. Lastly, run the below command to confirm that the Docker service is running properly.

sudo service docker status

The output below indicates the Docker service is active (running). As you see in the logs, the Docker metrics API is listening on 0.0.0.0:9323.

Verifying the Docker Service is Running
Verifying the Docker Service is Running

Accessing the Docker Metrics

Now that you’ve configured Docker for Grafana, feel free to access your raw and unrefined Docker metrics, but only in plain text format. You can access your Docker metrics via the endpoint you set in the daemon.json file.

Run the curl command below to view your Docker metrics via the localhost endpoint (http://localhost:9323/metrics).

curl -i <http://localhost:9323/metrics>

Your raw and unrefined Docker metrics (metric queries and values) should look similar to those below.

Accessing Docker Metrics
Accessing Docker Metrics

Since this tutorial focuses only on container state metrics, pipe the grep command to extract metrics on the state of available Docker containers.

curl -i <http://localhost:9323/metrics> | grep containers

The image below displays the queries and values for the different container states (paused, running, and stopped). The values for each query shown below are set to 0 for all the container states, indicating no containers are currently available.

Finding Docker Metric Queries for the Docker Container States
Finding Docker Metric Queries for the Docker Container States

Setting up Prometheus to Run on Docker

The Docker metrics are currently exposed via the endpoint you previously configured. Now it’s time to set up Prometheus to run on Docker via Docker-compose.

You’ll configure a job on Prometheus to scrape the Docker metric data from the exposed endpoint configured as a Prometheus target.

1. Run each command below to create a project directory (~/monitoring) and configuration directories as volumes for each service running via Docker-compose.

# Create a directory for prometheus.yml, 
# docker-compose.yml configuration file for the Prometheus,
# Grafana, NGINX, and Certbot container deployments
mkdir -p ~/monitoring/prometheus

# Create a directory for Grafana datasource configurations
mkdir -p ~/monitoring/grafana/provisioning/datasources

# Create a directory for NGINX configurations
mkdir -p ~/monitoring/nginx/conf

# Create www and conf directories for Certbot configurations
mkdir -p ~/monitoring/certbot/www
mkdir -p ~/monitoring/certbot/conf

# Set ~/monitoring directory as the working directory
cd monitoring

2. Next, create a file called prometheus.yml with your preferred editor in the ~/monitoring/prometheus directory, and populate the code below. Be sure to replace <YOUR_SERVER_IP> with your server’s IP address, and save the changes.

Without this file, Prometheus can’t scrape metrics and store them in a time-series database for analysis.

The following code configures Prometheus and the Docker metric endpoint as a target on Prometheus for scraping at set intervals.

# Set global configuration
global:
  scrape_interval:     15s # By default, scrape targets every 15 seconds.
  evaluation_interval: 15s # By default, scrape targets every 15 seconds.
  # scrape_timeout is set to the global default (10s).

  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
      monitor: 'my-project'

# Load and evaluate rules in this file every 'evaluation_interval' seconds.
rule_files:
  # - "first.rules"
  # - "second.rules"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries 
  # scraped from this config.

  - job_name: 'prometheus'

    # Override the global default and scrape targets from this job every 5 seconds.
    scrape_interval: 5s
    static_configs:
         - targets: ['localhost:9090']

  - job_name: 'docker-metrics'
    scrape_interval: 5s
    static_configs:
		# Replace <YOUR_SERVER_IP> with your server IP
      - targets: ['<YOUR_SERVER_IP>:9323']

3. Create another file called datasource.yml in the ~/monitoring/grafana/provisioning/datasources directory, add the code below and save the file.

The code below sets Prometheus as a data source on Grafana since Grafana requires a data source to pull data from.

# config file version
apiVersion: 1

# list of datasources to insert/update depending
# on what's available in the database
datasources:
  # <string, required> name of the datasource. Required
- name: Prometheus
  # <string, required> datasource type. Required
  type: prometheus
  # <string, required> access mode. direct or proxy. Required
  access: proxy
  # <string> url
  url: http://prometheus:9090

4. Lastly, create a file named grafana.config in the ~/monitoring/grafana/provisioning/ directory and add the configurations below.

The following lines set your Grafana admin password and user sign-up to false as you will not need the feature.

GF_SECURITY_ADMIN_PASSWORD=admin
GF_USERS_ALLOW_SIGN_UP=false

Running Prometheus and Grafana on Docker

You’ve created the necessary configurations and dependencies to run Prometheus and Docker. So it’s time to start up Prometheus and Grafana from the docker-compose.yml configuration file you will create shortly.

Create a configuration file called docker-compose.yml in your project’s root directory (~/monitoring), add the code below, save the file and close the editor.

The following configuration uses version 3.7 of the Docker-compose file format and defines all Prometheus and Grafana configurations.

version: '3.7'

# Persist data from Prometheus and Grafana with Docker volumes
volumes:
	prometheus_data: {}
	grafana_data: {}

# Connect containers via the front-tier and back-tier network
networks:
	backend:

# Container services
services:
	prometheus:
		# Prometheus uses the latest image
    image: prom/prometheus:latest

		# Stores Prometheus data locally in the prometheus directory
    volumes:
      - ./prometheus/:/etc/prometheus/
      - prometheus_data:/prometheus

		# Setup commands for Prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/usr/share/prometheus/console_libraries'
      - '--web.console.templates=/usr/share/prometheus/consoles'

		# Exposes port 9090 to access Prometheus web UI
    ports:
      - 9090:9090

		# Connects Prometheus service to the back-tier network
		networks:
      - backend

		# Restart policy for Prometheus service set to always
    restart: always

	grafana:
		# Grafana uses the latest image
    image: grafana/grafana:latest
		
		# Sets user ID to 472
    user: "472"
    depends_on:
      - prometheus
    ports:
      - 3000:3000
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning/:/etc/grafana/provisioning/
    env_file:
      - ./grafana/grafana.config
    networks:
      - backend
    restart: always

Now, run the docker-compose up command below to create a container in detached (-d) mode.

This command runs Prometheus and Grafana on Docker via Docker-composes as configured in the docker-compose.yml file.

sudo docker-compose up -d
Running Prometheus and Grafana on Docker via Docker-compose
Running Prometheus and Grafana on Docker via Docker-compose
Running Prometheus and Grafana on Docker via Docker-compose

Securing Grafana with NGINX and Let’s Encrypt

Your Grafana dashboard at this point can be accessed and intercepted by attackers. How to secure the dashboard? You’ll need NGINX to act as a reverse proxy to route traffic to your domain name. At the same time, you’ll set up SSL certificates with Let’s Encrypt to authenticate your server.

Create another docker-compose config file called docker-compose-nginx.yml in your project’s root directory (~/monitoring), and add the code below to the file.

The following code serves as NGINX and Certbot docker-compose service configurations, setting NGINX to listen to ports 80 for HTTP connections and 443 for HTTPS.

version: '3'

services:
# NGINX service
  nginx:
		# NGINX uses the latest image
    image: nginx:latest
    ports:
      - 80:80
      - 443:443
		# NGINX service restart policy set to "always"
    restart: always
		# Persist and share NGINX configuration data 
    volumes:
      - ./nginx/conf/:/etc/nginx/conf.d/
      - ./certbot/www:/var/www/certbot/
      - ./certbot/conf/:/etc/nginx/ssl/
# Certbot service
  certbot:
    image: certbot/certbot:latest
		# Persist and share Certbot configuration data
    volumes:
      - ./certbot/www/:/var/www/certbot/
      - ./certbot/conf/:/etc/letsencrypt/

2. Next, create a file named nginx.conf in the ~/monitoring/nginx/conf directory and add the configuration below to the nginx.conf file.

The code snippet below configures NGINX as a reverse proxy to route incoming traffic port through the default port 80 to the Grafana port 3000. Be sure to replace all occurrences of grafana.example.com with your Grafana endpoint URL.

Be sure to replace all occurrences of grafana.example.com on each code and command through this tutorial with your Grafana endpoint URL.

server {
				# Listen for incoming connections on port 80
        listen 80 default_server;
				# Set your Grafana endpoint URL
        server_name grafana.example.com;
        # Location to store certbot configurations
        location ~ /.well-known/acme-challenge/ {
           root /var/www/certbot;
        }
					 
        location / {
						# Assign incoming requests from port 80 to this URL
            proxy_pass http://grafana.example.com:3000/;
        }
}

3. Run the docker-compose command below to reload the NGINX container to apply the NGINX configurations (docker-compose-nginx.yml).

sudo docker-compose -f docker-compose-nginx.yml exec nginx nginx -s reload

As soon as you run the command, you’ll get the following output.

Reloading NGINX Container
Reloading NGINX Container

4. Now, run the below command to run the Certbot container and create the certificates in the /etc/letsencrypt/ directory. Be sure to change grafana.example.com with your domain name.

You can access the certificates stored in the /etc/letsencrypt/ directory locally in /certbot/conf.

# Change grafana.example.com to your Grafana URL
sudo docker-compose -f docker-compose-nginx.yml run \
 --rm certbot certonly --webroot \
 -w /var/www/certbot -d grafana.example.com

Once the certificates are created, you’ll get the following output.

Creating Certificates
Creating Certificates

5. Open the nginx.conf file and add the following code to allow access to Grafana via HTTPS:

server {
				# Listen for incoming connections on port 80
        listen 80 default_server;
				# Change grafana.example.com to your Grafana endpoint URL
        server_name grafana.example.com;
				# Return all HTTP requests to URL to HTTPS
        return 301 https://grafana.example.com$request_uri;
}

server {
				# Listen form incoming connections on port 443 via HTTPS
        listen 443 ssl http2;
				# SSL certificate and private key
				ssl_certificate     /etc/nginx/ssl/live/grafana.example.com/fullchain.pem;
        ssl_certificate_key /etc/nginx/ssl/live/grafana.example.com/privkey.pem;
				# Change grafana.example.com to your Grafana endpoint URL
        server_name grafana.example.com;
        
        location ~ /.well-known/acme-challenge/ {
					 # Location to store certbot configurations
           root /var/www/certbot;
        }
 
        location / {
						# Assign incoming requests from port 80 to this URL
            proxy_pass http://grafana.example.com:3000/;
        }
}

6. Next, run the following command to apply the modified NGINX configurations.

sudo docker-compose -f docker-compose-nginx.yml exec nginx nginx -s reload

7. Finally, open your favorite web browser and navigate to your domain name. This article uses the domain name grafana.joeshiett.xyz. You’ll get secure access to Grafana (login page) if all goes well, as shown below.

Accessing Grafana Securely with SSL Certificates
Accessing Grafana Securely with SSL Certificates

Creating Visualization in Grafana

With everything set up and running, you’re ready to create your first visualization in Grafana to view your Docker metrics. But you’ll first have to log in to Grafana to access your Grafana dashboard.

1. Log in to your Grafana with admin as the Username and Password.

Logging into Grafana Dashboard
Logging into Grafana Dashboard

Once logged in, you’ll be on the Grafana home page shown below.

Viewing Grafana’s Home Page
Viewing Grafana’s Home Page

2. Click on the + icon (left toolbar) and choose Dashboard to access your Grafana dashboard to see options for creating a new dashboard.

Navigating to Grafana Dashboard
Navigating to Grafana Dashboard

3. On the dashboard, click Add a new panel to create a panel where you can visualize your Docker metrics.

Adding a New Panel
Adding a New Panel

4. Now, click on the drop-down menu and select Prometheus, as shown below, to add Prometheus to the panel as a Data source.

Adding Prometheus Data Source
Adding Prometheus Data Source

5. Add the following Docker metric query to the Metric browser field to get the different states of available Docker containers.

```bash
engine_daemon_container_states_containers{}
```
Running Docker Metric Query
Running Docker Metric Query

To query for specific Docker state on Grafana, run the following queries: engine_daemon_container_states_containers{state=”running”} engine_daemon_container_states_containers{state=”paused”} engine_daemon_container_states_containers{state=”stopped”}

6. Next, click the drop-down menu (top-right of the page) to see other types of visualization you can choose.

Accessing Visualization Menu
Accessing Visualization Menu

7. Choose your preferred visualization from the list, but this tutorial uses the Stat visualization.

Setting Stat Visualization
Setting Stat Visualization

If you choose the Stat visualization, your new dashboard should look similar to the one below.

For this tutorial, the number 3 represents three running containers, 1 represents one stopped container, and 0 represents no paused container.

Viewing Stat Visualization
Viewing Stat Visualization

8. Change the panel Title as you like under Panel options (right panel) and click on Save (top-right). The panel title is set to Docker States in this tutorial.

After saving the title, a pop-up window appears where you’ll set a name for your dashboard (step nine).

Saving the Panel Title
Saving the Panel Title

9. Finally, name the dashboard as you like, but the dashboard is called Docker Metrics in this tutorial. Once you’re happy with the dashboard name, click on the Save button to save the dashboard.

Saving Dashboard
Saving Dashboard

Your dashboard (Docker Metrics) should now be available on your Grafana Home page, as shown below.

At this point, you now have a fully functional dashboard you can use to monitor your Docker metrics.

Dashboard available on Grafana Home page
Dashboard available on Grafana Home page

Conclusion

In this tutorial, you learned how to export Docker metrics to Prometheus via the configured endpoint and made queries on Prometheus to display their values. You’ve also configured Prometheus as a data source on Grafana and finally created a sample dashboard to better view the values obtained from the metric query.

To build on this newfound knowledge, why not set up alerts with Alertmanager, and set up both Prometheus and Grafana on a separate dedicated Ubuntu server? You can also configure more dashboards to your heart’s content so you can view more metrics on your Grafana Home page.

Hate ads? Want to support the writer? Get many of our tutorials packaged as an ATA Guidebook.

Explore ATA Guidebooks

Looks like you're offline!