In this post I describe how I’ve reinvented the wheel backup Grafana dashboards with API and Git.

Use case

I run Grafana in a Docker container in my homelab .

After a few mistakes tests with Docker Volumes I was tired to lose the fine-tuned dashboards I made in Grafana.

So I’ve used some unproductive time waiting for people to join meetings spare time to build a simple script to export the Dashboards and save them to a local Git repository.

The script

Use the script at your own risk. Code is provided as-is, no guarantee.

We start creating a token to access the API using the Grafana web GUI, the procedure is described here .

The first action is to set the token and grafanaurl.

It’s not a best practice to set tokens inside the code.

export grafanaurl=

Then we use curl to collect the list of the Dashboards in Grafana. The output is a JSON file.

out=$(curl -s -H "Authorization: Bearer $token" -X GET $grafanaurl/search?folderIds=0&query=&starred=false)

What we need now is the list of uid of the dashboards, to get them one by one and dump the resulting JSON to a local file.

For that purpose I use one of my favorite tools: jq :

for uid in $(echo $out | jq -r '.[] | .uid'); do
  curl -H "Authorization: Bearer $token" $grafanaurl/dashboards/uid/$uid | jq > grafana-dashboard-$uid.json
  echo "DASH $uid EXPORTED"

Update: add Datasources to the backup

datasources=$(curl -s -H "Authorization: Bearer $token" -X GET $grafanaurl/datasources)
for uid in $(echo $datasources | jq -r '.[] | .uid'); do
  curl -s -H "Authorization: Bearer $token" -X GET $grafanaurl/datasources/uid/$uid | jq > datasource-$uid.json
  echo "DATASOURCE $uid exported"

The job of the last part of the script is to add/commit the files to the local Git folder and push them to the remote repository:

git add .
timestamp=$(date +"%Y-%m-%dT%H:%M:%S")
git commit -a -m "update $timestamp"
git push

That’s it!

The full scripts is available as Gist:

The script should be executed in a folder manager by Git. Store the credentials with git-credential-store to run it without user intervention.


The last step is to schedule the script. I set it to run every 8 hours adding a line to crontab.


crontab -e

Add this lines, change the file path and name

0 */8 * * * ~/code/cargo-grafana-backup/