Cloud Native 19 min read

How to Safely Backup and Restore Grafana Dashboards in Kubernetes with Scripts and Docker

This guide walks through recovering lost Grafana data in a Kubernetes cluster by using low‑level shell scripts, the grafana‑backup‑tool, Docker images, GitHub Actions, and Podman deployments, covering export/import commands, component selection, and handling provisioned dashboards.

Programmer DD
Programmer DD
Programmer DD
How to Safely Backup and Restore Grafana Dashboards in Kubernetes with Scripts and Docker

Preface

Our k8s cluster uses Grafana with Ceph storage; deleting and recreating the Grafana Deployment caused all data loss because the new PV points to a fresh location.

1. Low‑level solution

We searched for Grafana backup scripts that call the Grafana API via shell; the gist at https://gist.github.com/crisidev/bd52bdcc7f029be2f295 contains several useful scripts.

Export script

#!/bin/bash
# Usage: export_grafana_dashboards.sh https://admin:[email protected]

create_slug () {
  echo "$1" | iconv -t ascii//TRANSLIT | sed -r s/[^a-zA-Z0-9]+/-/g | sed -r s/^-+|-+$//g | tr A-Z a-z
}

full_url=$1
username=$(echo "$full_url" | cut -d/ -f3 | cut -d: -f1)
base_url=$(echo "$full_url" | cut -d@ -f2)
folder=$(create_slug "$username-$base_url")

mkdir "$folder"
for db_uid in $(curl -s "$full_url/api/search" | jq -r .[].uid); do
  db_json=$(curl -s "$full_url/api/dashboards/uid/$db_uid")
  db_slug=$(echo "$db_json" | jq -r .meta.slug)
  db_title=$(echo "$db_json" | jq -r .dashboard.title)
  filename="$folder/${db_slug}.json"
  echo "Exporting \"$db_title\" to \"$filename\"..."
  echo "$db_json" | jq -r . > "$filename"
done
echo "Done"

This script exports all dashboards as JSON files but places them under the General folder, which is not ideal.

Import script

Use grafana-dashboard-importer.sh with a running Grafana instance and an admin API key.

# Usage: ./grafana-dashboard-importer.sh -t http://<grafana_ip>:<grafana_port> -k <api_key> -p <backup_folder>

The -p flag points to the directory containing the exported JSON files.

The low‑level approach cannot back up datasources, users, or folders.

2. Advanced solution

The grafana-backup-tool supports backing up folders, dashboards, datasources, alert channels, organizations and users.

Dockerfile

FROM alpine:latest
LABEL maintainer="grafana-backup-tool Docker Maintainers https://fuckcloudnative.io"
ENV ARCHIVE_FILE ""
RUN echo "@edge http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories && \
    apk --no-cache add python3 py3-pip py3-cffi py3-cryptography ca-certificates bash git && \
    git clone https://github.com/ysde/grafana-backup-tool /opt/grafana-backup-tool && \
    cd /opt/grafana-backup-tool && \
    pip3 --no-cache-dir install . && \
    chown -R 1337:1337 /opt/grafana-backup-tool
WORKDIR /opt/grafana-backup-tool
USER 1337

A GitHub Actions workflow builds multi‑arch images and pushes them to Docker Hub and GHCR.

# GitHub Actions workflow (simplified)
name: Build and push grafana-backup-tool Docker image
on:
  push:
    branches: [master]
    paths:
      - 'grafana-backup-tool/Dockerfile'
      - '.github/workflows/grafana-backup-tool.yml'
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v1
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
      - name: Login to DockerHub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - name: Build and push
        uses: docker/build-push-action@v2
        with:
          file: 'grafana-backup-tool/Dockerfile'
          platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x
          context: grafana-backup-tool
          push: true
          tags: |
            yangchuansheng/grafana-backup-tool:latest
            ghcr.io/yangchuansheng/grafana-backup-tool:latest

After building the image, you can run the backup tool in a container, a Kubernetes Deployment, or a Podman pod.

Podman deployment example

apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana-backup
  labels:
    app: grafana-backup
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana-backup
  template:
    metadata:
      labels:
        app: grafana-backup
    spec:
      containers:
      - name: grafana-backup
        image: yangchuansheng/grafana-backup-tool:latest
        command: ["/bin/bash"]
        tty: true
        stdin: true
        env:
        - name: GRAFANA_TOKEN
          value: "<redacted>"
        - name: GRAFANA_URL
          value: "http://<grafana_ip>:<grafana_port>"
        - name: GRAFANA_ADMIN_ACCOUNT
          value: "admin"
        - name: GRAFANA_ADMIN_PASSWORD
          value: "admin"
        - name: VERIFY_SSL
          value: "False"
        volumeMounts:
        - name: data
          mountPath: /opt/grafana-backup-tool
      volumes:
      - name: data
        hostPath:
          path: /mnt/manifest/grafana/backup

Run the pod with podman play kube grafana-backup-deployment.yaml, then execute grafana-backup save inside the container. The tool backs up all components by default; you can limit components with --components=folders,dashboards and restore with grafana-backup restore.

Handling Provisioned Dashboards

Grafana dashboards provisioned by the Prometheus Operator cannot be deleted via the UI, and grafana-backup-tool will fail if they already exist. Work‑arounds are to remove the provisioning configuration from the Grafana Deployment or to deploy Grafana without provisioning.

For a complete list of supported components and usage examples, refer to the tool's README.

Grafana API key creation
Grafana API key creation
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Dockerci/cdKubernetesShellBackupGrafana
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.