Grafana logo

Grafana is a leading observability platform for metrics visualization. It lets you build bespoke dashboards to surface meaningful insights from your application’s real-time data streams.

Grafana’s a cloud-native application that’s ready to be launched on popular infrastructure providers, installed on your own hardware, or deployed as a standalone container. In this guide we’ll focus on the latter choice by using the official Grafana image to start an instance that runs in Docker.

Getting Started

The simplest Grafana container creation looks like this:

docker run -d --name=grafana -p 3000:3000 grafana/grafana

image of starting a Grafana Docker container

You’ll have a fresh Grafana server accessible on port 3000. Visit http://localhost:3000 and login as admin/admin.

image of the Grafana dashboard after installation

Now you can start adding data sources and dashboards to create your visualizations. Press the “Add your first data source” button on the homepage to connect a new source; select the provider type on the following screen, then fill in the details so Grafana can access your data.

image of adding a Prometheus data source to Grafana

Next return to the homepage and click “Create your first dashboard.” Choose your preferred visualization type and then use the query pane to select the appropriate metrics from your data. Once you’re finished, your new visualization will show on your dashboard.

image of an empty Grafana dashboard

This procedure demonstrates how easily you can start a disposable Grafana test instance. Running a production-ready container requires a little more thought though. Here’s a more complete approach that’s better equipped for long-term use.

Selecting an Image Variant

Grafana uses a dual-license business model. The open-source edition is published as grafana/grafana on Docker Hub whereas Enterprise is grafana/grafana-enterprise. The following instructions will work with both of these top-level variants.

Multiple Grafana versions are available, each in either Alpine or Ubuntu flavors. Alpine should be preferred in most deployment situations: it’s slimmer and focused on providing a Grafana-compatible environment without any superfluous extras.

The OS is selected by appending its name after the Grafana version in an image tag:

grafana/grafana:8.3.0-ubuntu

It’s always best to pin to a specific release so you don’t unintentionally receive breaking changes as new updates are published. Omitting the OS name (grafana/grafana:8.3.0) will give you the Alpine variant of your selected version.

Creating a Container

Grafana has relatively straightforward deployment requirements. You need to mount a Docker volume to store your persistent data and bind a host port so you can access the service. Settings can be supplied by mounting a config file into the container or injecting environment variables.

docker run -d --name grafana -p 9000:3000 
    -v grafana-data:/var/lib/grafana
    grafana/grafana:8.3.0

This example starts a new Grafana container called grafana that listens on port 9000 on your Docker host. The port is bound to 3000 in the container as this is Grafana’s default listening address.

A Docker volume called grafana-data is referenced by the -v flag. It’s mounted to /var/lib/grafana within the container, where Grafana stores all its generated data. The volume mount means the directory’s contents will be stored outside the container, avoiding data loss when the container stops or your host restarts.

Injecting Configuration

You can override Grafana’s config keys by setting environment variables when you start your container. You can change any of the keys in Grafana’s INI-format config files by capitalizing the key name and prepending GF_:

# INI file
instance_name = my-grafana

[security]
admin_user = demo
admin_password = grafana

---

# Corresponding environment variables
GF_DEFAULT_INSTANCE_NAME=my-grafana
GF_SECURITY_ADMIN_USER=demo
GF_SECURITY_ADMIN_PASSWORD=grafana

Make sure you include the implicit DEFAULT section name when you’re changing the value of a top-level variable in the config file.

Once you’ve worked out which values you want to change, supply the correct environment variables with -e flags when you start your container:

docker run -d --name grafana -p 9000:3000 
    -e GF_DEFAULT_INSTANCE_NAME=my-grafana
    -e GF_SECURITY_ADMIN_USER=demo
    -e GF_SECURITY_ADMIN_PASSWORD=grafana
    -v grafana-data:/var/lib/grafana
    grafana/grafana:8.3.0

Grafana supports file-based configuration too. With this mechanism the value of the target environment variable becomes the path to a file available inside the container. Grafana will obtain the setting’s real value by reading the file.

To use this approach, modify any environment variable by suffixing __FILE to its regular name:

docker run -d --name grafana -p 9000:3000 
    -e GF_DEFAULT_INSTANCE_NAME=my-grafana
    -e GF_SECURITY_ADMIN_USER=demo
    -e GF_SECURITY_ADMIN_PASSWORD__FILE=/run/secrets/password
    -v grafana-data:/var/lib/grafana
    grafana/grafana:8.3.0

You can add the file to the container using a bind mount (-v ./password.txt:/run/secrets/password) or a dedicated secrets management system such as Docker Secrets. File-based configuration provides a safer way to inject sensitive values that you’d rather not expose as plain text in CI job logs and your shell’s history.

Overriding the Config File

You can always override Grafana’s on-disk configuration file if you’re changing too many values for environment variables to be convenient.

The Docker image locates this file at /etc/grafana/grafana.ini. You can mount a replacement to the expected path using a Docker bind mount:

docker run -d --name grafana -p 9000:3000 
    -v ./grafana.ini:/etc/grafana/grafana.ini
    -v grafana-data:/var/lib/grafana
    grafana/grafana:8.3.0

Using a config file eases the injection of more complicated settings. You can interpolate variables to build up dynamic values. Config files also support comments that let you document your intentions to help future maintainers.

Managing Plugins

Many Grafana installations require plugins that add extra data sources or provide pre-built dashboard panels. The Docker image includes a helper utility that lets you add plugins to a new container by setting a special environment variable.

Here’s how to add an official plugin that’s listed in the Grafana catalog:

docker run -d --name grafana -p 9000:3000 
    -e GF_INSTALL_PLUGINS=grafana-simple-json-datasource
    -v grafana-data:/var/lib/grafana
    grafana/grafana:8.3.0

The GF_INSTALL_PLUGINS variable expects a comma-separated list of plugin names to install when the container first starts. The names will be passed to the grafana-cli plugins install command. This means you can include version expressions, such as grafana-simple-json-datasource 1.1.0, and reference community plugins via their URL:

docker run -d --name grafana -p 9000:3000 
    -e GF_INSTALL_PLUGINS=https://example.com/grafana-plugin.zip
    -v grafana-data:/var/lib/grafana
    grafana/grafana:8.3.0

Creating a Custom Image

Manually bringing up Grafana containers with configuration supplied via docker run flags is repetitive and error-prone. Building your own Docker image with your modifications included saves time and centralizes settings when multiple team members need to be able to spin up a new instance.

You can achieve this by writing a Dockerfile that extends the official grafana/grafana image. This gives you an opportunity to copy in a custom config file and set any extra environment variables you need.

FROM grafana/grafana:8.3.0

# Add plugins
ENV GF_INSTALL_PLUGINS=grafana-simple-json-datasource

# Copy a config file from your working directory
COPY grafana.ini /etc/grafana/grafana.ini

Use your Dockerfile to build your new Grafana image:

docker build -t custom-grafana:latest .

image of building a custom Grafana Docker image

Now you can start a preconfigured container instance from your image:

docker run -d --name grafana -p 9000:3000 
    -v grafana-data:/var/lib/grafana
    custom-grafana:latest

This approach is particularly useful when you’ve made extensive modifications to your Grafana environment. You can now reliability reproduce your configuration each time you start a container. This also helps version changes to your installation over time.

One drawback is the need to rebuild your image when upstream Grafana updates are published. You’ll have to periodically pull grafana/grafana, docker build your image, push it to a registry, and then pull the new version on your Docker host. The final stage is to recreate your running containers so they use the updated image.

Summary

Docker simplifies Grafana installation and set up by providing an isolated environment in which you can host your observability platform. You can quickly start new Grafana instances by binding a host port, mounting a data volume, and supplying config values via environment variables. Later you can encapsulate your configuration in your own reusable image that builds on the official base.

Once it’s and up and running, a Dockerized Grafana installation works just like a regular one. You can connect data sources, interact with the HTTP API, and configure alerts by pointing to the host port you bound to your container. You could also assign your instance a domain name and set up HTTPS by serving it behind a reverse proxy such as Apache or Traefik.

Profile Photo for James Walker James Walker
James Walker is a contributor to How-To Geek DevOps. He is the founder of Heron Web, a UK-based digital agency providing bespoke software development services to SMEs. He has experience managing complete end-to-end web development workflows, using technologies including Linux, GitLab, Docker, and Kubernetes.
Read Full Bio »