Plugins 〉Grafana Image Renderer
Grafana Image Renderer
A Grafana backend plugin that handles rendering panels and dashboards to PNGs using a headless browser (Chromium).
Requirements
Supported operating systems
- Linux (x64)
- Windows (x64)
- Mac OS X (x64)
For Mac ARM64, you need to build the plugin from source or use the remote rendering installation.
Dependencies
This plugin is packaged in a single executable with Node.js runtime and Chromium browser. This means that you don't need to have Node.js and Chromium installed in your system for the plugin to function.
However, the Chromium browser depends on certain libraries. If you don't have all of those libraries installed in your system, you may see some errors when you try to render an image. For more information including troubleshooting help, refer to Grafana Image Rendering documentation.
Memory requirements
Rendering images requires a lot of memory, mainly because Grafana creates browser instances in the background for the actual rendering. We recommend a minimum of 16GB of free memory on the system rendering images.
Rendering multiple images in parallel requires an even bigger memory footprint. You can use the remote rendering service in order to render images on a remote system, so your local system resources are not affected.
Installation
We offer two installation methods: as a plugin and as a remote service. We always recommend using the remote service if possible, as this is how we deploy the service in Grafana Cloud, and thus gets the most attention in bug handling.
I deploy Grafana in Docker/Kubernetes/...: Use the Docker image.
I deploy Grafana as a user/in systemd/...:
- Prefer the Docker image with
--networking=host
passed to the Docker container. - If that is not fitting, prefer the standalone server.
- If that is not fitting, use the plugin.
Docker image (recommended)
If you want to run the service as a Docker container, use the Docker image we publish to DockerHub.
With docker run
:
$ docker network create grafana
$ docker run --network grafana --name renderer --rm --detach grafana/grafana-image-renderer:latest
# The following is not a production-ready Grafana instance, but shows what env vars you should set:
$ docker run --network grafana --name grafana --rm --detach --env GF_RENDERING_SERVER_URL=http://renderer:8081/render --env http://grafana:3000/ --port 3000:3000 grafana/grafana-enterprise:latest
With docker compose
:
services:
renderer:
image: grafana/grafana-image-renderer:latest
grafana:
image: grafana/grafana-enterprise:latest
ports:
- ‘3000:3000’
environment:
GF_RENDERING_SERVER_URL: http://renderer:8081/render
GF_RENDERING_CALLBACK_URL: http://grafana:3000/
With Kubernetes, see our k3s setup.
Run as standalone Node.js application
The following example describes how to build and run the remote HTTP rendering service as a standalone Node.js application and configure Grafana appropriately.
Clone the Grafana image renderer plugin Git repository.
Install dependencies and build:
yarn install --pure-lockfile yarn run build
Run the server:
- Using default configuration:
node build/app.js server
- Using custom configuration:
node build/app.js server --config=dev.json
- Using environment variables:
HTTP_PORT=8085 LOG_LEVEL=debug node build/app.js server
- Using default configuration:
Update Grafana configuration:
[rendering] server_url = http://localhost:8081/render callback_url = http://localhost:3000/
Restart Grafana.
Plugin: Grafana CLI
You can install the plugin with Grafana CLI:
$ grafana cli plugins install grafana-image-renderer
# alternatively, if you want to install a specific version:
$ grafana cli plugins install grafana-image-renderer $VERSION
Please run this as the same user that Grafana runs as, otherwise the plugin may not work!
Security
Access to the rendering endpoints is restricted to requests providing an auth token. This token should be configured in the Grafana configuration file and the renderer configuration file. This token is important when you run the plugin in remote rendering mode to avoid unauthorized file disclosure (see CVE-2022-31176).
See Grafana Image Rendering documentation to configure this secret token. The default value -
is configured on both Grafana and the image renderer when you get started but we strongly recommend you to update this to a more secure value.
Configuration
For available configuration settings, please refer to Grafana Image Rendering documentation.
Troubleshooting
For troubleshooting help, refer to Grafana Image Rendering troubleshooting documentation.
Grafana Cloud Free
- Free tier: Limited to 3 users
- Paid plans: $55 / user / month above included usage
- Access to all Enterprise Plugins
- Fully managed service (not available to self-manage)
Self-hosted Grafana Enterprise
- Access to all Enterprise plugins
- All Grafana Enterprise features
- Self-manage on your own infrastructure
Grafana Cloud Free
- Free tier: Limited to 3 users
- Paid plans: $55 / user / month above included usage
- Access to all Enterprise Plugins
- Fully managed service (not available to self-manage)
Self-hosted Grafana Enterprise
- Access to all Enterprise plugins
- All Grafana Enterprise features
- Self-manage on your own infrastructure
Grafana Cloud Free
- Free tier: Limited to 3 users
- Paid plans: $55 / user / month above included usage
- Access to all Enterprise Plugins
- Fully managed service (not available to self-manage)
Self-hosted Grafana Enterprise
- Access to all Enterprise plugins
- All Grafana Enterprise features
- Self-manage on your own infrastructure
Grafana Cloud Free
- Free tier: Limited to 3 users
- Paid plans: $55 / user / month above included usage
- Access to all Enterprise Plugins
- Fully managed service (not available to self-manage)
Self-hosted Grafana Enterprise
- Access to all Enterprise plugins
- All Grafana Enterprise features
- Self-manage on your own infrastructure
Grafana Cloud Free
- Free tier: Limited to 3 users
- Paid plans: $55 / user / month above included usage
- Access to all Enterprise Plugins
- Fully managed service (not available to self-manage)
Self-hosted Grafana Enterprise
- Access to all Enterprise plugins
- All Grafana Enterprise features
- Self-manage on your own infrastructure
For more information, visit the docs on plugin installation.
Installing on a local Grafana:
For local instances, plugins are installed and updated via a simple CLI command. Plugins are not updated automatically, however you will be notified when updates are available right within your Grafana.
1. Install the Renderer
Use the grafana-cli tool to install Grafana Image Renderer from the commandline:
grafana-cli plugins install
The plugin will be installed into your grafana plugins directory; the default is /var/lib/grafana/plugins. More information on the cli tool.
Alternatively, you can manually download the .zip file for your architecture below and unpack it into your grafana plugins directory.
4.0.11 (2025-09-01)
- CI: Configure Renovate and pin dependencies, #712 + #723 + #734, lucychen-grafana
- Docker: Update Chromium (CVE-2025-8879, CVE-2025-8880, CVE-2025-8901, CVE-2025-9478) #754, macabu
4.0.10 (2025-07-31)
- Docker: Update Chromium (CVE-2025-8292), #695, macabu
- Tests: Add Docker image test suite, #693, Proximyst
- Docker: Inherit permissions from user, #697, Proximyst
- This fixes #694, which applies to RedHat OpenShift users. It was reported by @mcapala. Thanks!
4.0.9 (2025-07-28)
- Docker: Use numeric UID, #686, Proximyst
- This fixes #686, which is useful for some Kubernetes users. It was reported by @mhulscher. Thanks!
- The bug only manifests if you use
securityContext.runAsNonRoot
in yourDeployment
.
4.0.8 (2025-07-28)
4.0.7 (2025-07-25)
4.0.6 (2025-07-24)
4.0.5 (2025-07-23)
- Docker: Use tini, #678, Proximyst
- This fixes #677, reported by @mbentley. Thanks!
- Docker: Include ca-certificates package, #679, Proximyst
- This fixes #676, reported by @roock. Thanks!
4.0.1, 4.0.2, 4.0.3 & 4.0.4 (2025-07-22)
This release only touches the build process of the plugin, as v4.0.0, .1, .2, and .3 did not release on the plugin catalog. There is no difference from v4.0.0 for Docker users.
4.0.0 (2025-07-22)
- Build: Update all dependencies, #663, Proximyst
- Docker: Update Chromium (CVE-2025-6558, CVE-2025-7656, CVE-2025-7657), #667, Proximyst
Breaking changes:
- Build: Bump minimum Node.js version from v20 to v22 (LTS), #663, Proximyst
- If you use the Docker image, you will not have to update anything.
- If you run grafana-image-renderer yourself, you may need to update Node.js.
- Plugin: Update minimum Grafana version to 11.3.8, #663, Proximyst
- If you use any Grafana version newer than 11.3.8 (incl. 11.4.x, 11.5.x, 11.6.x, 12.x), you will not have to do anything.
- If you are not in that group, you must update Grafana before updating.
- Docker: Move to distroless Debian, #661, Proximyst
- In practice, this SHOULD come with no changes for most users.
- If you are building a new Docker image on top of us, you will have to adapt to distroless Debian instead of Alpine.
3.12.9 (2025-07-01)
3.12.8 (2025-06-25)
3.12.7 (2025-06-19)
- Chore: Update base Docker image to latest (CVE-2025-5959), #647, #648, macabu, Proximyst
- Tracing: Add debug logs when verbose logging is enabled #644, AgnesToulet
3.12.6 (2025-05-23)
- Chore: Upgrade multer 2.0.0 #642, evictorero
- Tracing: Fix tracing headers causing CORS issue #640, AgnesToulet
- Tracing: improve logs #639, AgnesToulet
- Image Render: Support tracing #612, lucychen-grafana
- CI: Fix Docker secrets #636, AgnesToulet
- Server: Add rate limiter #627, AgnesToulet
- Bump formidable from 3.5.2 to 3.5.4 #634, dependabot[bot]
- CI: improve workflow security #635, AgnesToulet
3.12.5 (2025-04-22)
- PDF: Use sent timeout #628, AgnesToulet
- Docker: Remove unused NPM files #625, AgnesToulet
- Docker: Add chromium-swiftshader to support webGL #623, AgnesToulet
3.12.4 (2025-03-27)
- Chore: Update dompurify to fix CVE #614, lucychen-grafana
- Chore: Downgrade to Node 20 #619, evictorero
3.12.3 (2025-03-12)
- 3.12.2 does not work due to Image Render: Support Tracing #586. Revert "Image Render: Support Tracing (#586)" #609, lucychen-grafana
3.12.2 (2025-03-06) (DEPRECATED)
- Image Render: Support Tracing #586, lucychen-grafana
- Server: Support HTTPS configuration using env variables #600, evictorero
- Docs: Update run server options #599, evictorero
- Chore: Upgrade to Node 22 #595, AgnesToulet
3.12.1 (2025-02-10)
- Chore: upgrade deps #593, AgnesToulet
- Logs: Redirect log in response #589, juanicabanas
- Metrics: Exclude /render/version from duration and inflight metrics #591, AgnesToulet
3.12.0 (2025-01-14)
- Support cancel rendering requests on client cancellation #588, AgnesToulet
- Chore: Add ENV variables for temp folders in Docker #583, evictorero
- Add image source label to dockerfiles #573, wuast94
3.11.6 (2024-10-17)
- Chore: Upgrade express from 4.21.0 to 4.21.1 #577, AgnesToulet
- Chore: Don't install dev packages in Docker image #575, McTonderski, AgnesToulet
- Bump dompurify from 2.4.7 to 2.5.4 #574, dependabot[bot]
3.11.5 (2024-09-12)
- Bump express to 4.21.0 #567, evictorero
- Bump micromatch from 4.0.7 to 4.0.8 #561, dependabot[bot]
3.11.4 (2024-08-30)
- Puppeteer: Upgrade to v22 #556, evictorero
3.11.3 (2024-08-13)
- Full page image: Fix blank page screenshot when scenes is turned on #554, juanicabanas
3.11.2 (2024-08-08)
- Properly support dashboards where the scrollable element is the document #552, ashharrison90
3.11.1 (2024-07-15)
- Full page image: Fix wait condition for dashboard with rows #542, AgnesToulet
- Chore: Upgrade Jimp deps 541, AgnesToulet
3.11.0 (2024-06-13)
- Chore: Upgrade chokidar and jest dependencies #532, AgnesToulet
- Bump @grpc/grpc-js from 1.8.20 to 1.8.22 #531, dependabot[bot]
- Server: Fix CSV deletion #530, AgnesToulet
- Server: Support HTTPS configuration #527, AgnesToulet
3.10.5 (2024-05-23)
- Packages: Release Alpine package without Chromium #525, AgnesToulet
- Full page image: Fix scrolling with the new native scroll #524, AgnesToulet
3.10.4 (2024-05-06)
- Chore: Remove unused dependencies #517, evictorero
3.10.3 (2024-04-16)
- Bump protobufjs from 7.2.4 to 7.2.6 #515, dependabot[bot]
3.10.2 (2024-04-08)
- Bump express from 4.18.2 to 4.19.2 #510, dependabot[bot]
- Bump follow-redirects from 1.15.5 to 1.15.6 #508, dependabot[bot]
3.10.1 (2024-03-07)
- Bump axios from 1.6.0 to 1.6.7 #503, evictorero
- Bump ip from 1.1.8 to 1.1.9 #500, dependabot[bot]
- PDF: Fix resolution when zooming in #502, AgnesToulet
3.10.0 (2024-02-20)
- WaitingForPanels: Change waiting logic for Scenes #496, torkelo
- Experimental: Support PDF rendering #487, ryantxu
3.9.1 (2024-01-29)
- Chore: Upgrade jimp and node #492, AgnesToulet
- Bump follow-redirects from 1.15.3 to 1.15.4 #489, dependabot[bot]
3.9.0 (2023-12-04)
- Config: Improve consistency between plugin and server mode #477, AgnesToulet
- Chore: Bump axios from 0.27.2 to 1.6.0 #480, dependabot[bot]
3.8.4 (2023-10-17)
- Bump xml2js to 0.6.2 #473, AgnesToulet
- Browser: Fix panel rendered waiting condition #472, AgnesToulet
- Docker: Add build for arm64 #468, michbeck100
- Fix timezone config always overwritten #463, zhichli
3.8.3 (2023-09-29)
- Chore: Upgrade to Node 18 #448, Clarity-89
3.8.2 (2023-09-21)
- Browser: Revert to old headless mode to fix usage with Kubernetes #459, AgnesToulet
3.8.1 (2023-09-18)
- Fix check condition to avoid timeouts in invalid panels #299, spinillos
- Plugin: fix Chrome path #451, AgnesToulet
3.8.0 (2023-08-22)
- Puppeteer: upgrade to v21 #433, Clarity-89
- Fix fullpage waitFor conditions #446, AgnesToulet
3.7.2 (2023-07-27)
- Chore: update all dependencies #443, AgnesToulet
- Bump protobufjs from 7.1.1 to 7.2.4 #438, dependabot[bot]
- Bump tough-cookie from 4.1.2 to 4.1.3 #439, dependabot[bot]
- Bump semver from 6.3.0 to 6.3.1 #440, dependabot[bot]
- Bump word-wrap from 1.2.3 to 1.2.4 #441, dependabot[bot]
3.7.1 (2023-05-15)
- Docker: remove alpine edge repo #413, sozercan
- Bump yaml from 2.1.1 to 2.2.2 #421, dependabot[bot]
3.7.0 (2023-04-17)
- Security: can set array of auth tokens #417, AgnesToulet
- Bump pkg from 5.8.0 to 5.8.1 #415, AgnesToulet
- Bump jimp from 0.16.1 to 0.16.13 #406, AgnesToulet
3.6.4 (2023-02-10)
- Add Snyk workflow #402, SadFaceSmith
- Fix null error #403, spinillos
3.6.3 (2023-01-11)
- Add support for page zooming option #387, kaffarell
- Migrate from CircleCI to Drone #394, spinillos, joanlopez
3.6.2 (2022-10-22)
- Log errors related to JSHandle@object as debug #376, spinillos
- Chore: Update Puppeteer deprecated functions #375, spinillos
- Fix: Update _client with _client() to avoid to fail when creating a CSV #372, spinillos
- Chore: Update all dependencies #369, DanCech
3.6.1 (2022-08-30)
- Chore: Update to Node 16 #365, Clarity-89
- Update waiting condition for full page screenshots #362, spinillos
- Fix invalid Content-Disposition #357, spinillos
3.6.0 (2022-08-16)
3.5.0 (2022-07-18)
- Added File Sanitization API with DOMPurify as the backend. #349, ArturWierzbicki
- Security: upgrade dependencies #356, #348, #347, AgnesToulet
3.4.2 (2022-03-23)
- Security: upgrade dependencies #337, AgnesToulet
- Fix: set captureBeyondViewport to false by default to fix rendering old panels #335, AgnesToulet
3.4.1 (2022-02-23)
- Fix: replace
sharp
withjimp
to resolve issues with installing native dependencies #325, ArturWierzbicki
3.4.0 (2022-02-17)
- Support new concurrency mode: contextPerRenderKey #314, ArturWierzbicki
- Support full height dashboards and scaled thumbnails #312, ryantxu
3.3.0 (2021-11-18)
- Chore: Bump pkg from 5.3.3 to 5.4.1 #305, AgnesToulet
- Configuration: Add timeout setting for clustered mode #303, AgnesToulet
3.2.1 (2021-10-07)
- Chore: Upgrade dev dependencies #294, AgnesToulet
- Chore: Fix eslint usage #293, AgnesToulet
- Docs: Fix links in README.md #290, simonc6372
- Security: Bump semver-regex from 3.1.2 to 3.1.3 #289, dependabot[bot]
3.2.0 (2021-09-17)
- Docs: Update documentation to improve visibility and avoid duplicates with Grafana documentation #277, AgnesToulet
- Instrumentation: Update grafana_image_renderer_step_duration_seconds buckets #287, AgnesToulet
- Security: Bump chokidar from 3.5.1 to 3.5.2 #284, AgnesToulet
- Instrumentation: Add gauge of total number of requests in flight #281, AgnesToulet
- Security: Bump axios from 0.21.1 to 0.21.4 #283, dependabot[bot]
- Chore: Add self-contained setup for load test #275, pianohacker
3.1.0 (2021-09-01)
- Settings: Set the maximum device scale factor to 4 as default #276, AgnesToulet
- Metrics: Add browser timing metrics #263, AgnesToulet
- Settings: Add --disable-gpu in the default Chromium args #262, AgnesToulet
- Security: Update path-parse to v1.0.7 #268, joanlopez
- Chore: Upgrade dependencies #246, Clarity-89
- Docker: Run image renderer under non-root Grafana user #144, wardbekker
Important change
The default Chromium flags have been updated to include --disable-gpu
as it fixes memory leaks issues when using the default
rendering mode. If you don't want to use this flag, you need to update your service configuration, either through the service configuration file, the environment variables or the Grafana configuration file (if you're using the plugin mode).
3.0.1 (2021-06-10)
- Browser: Fix panel timezone when the timezone query parameter is specified #224, Bujupah
- Docker: Fix version endpoint for Docker images #248, mbentley
3.0.0 (2021-06-07)
- Security: Bump path-parse from 1.0.6 to 1.0.7 #244, AgnesToulet
- HTTP Server: Add version endpoint to get the current version #239, AgnesToulet
- Security: Bump ws from 7.4.5 to 7.4.6 #238, dependabot[bot]
- Remove support for plugin V1 protocol #233, AgnesToulet
- Browser: Fix moving CSV file when the tmp folder is not on the same device as the target file path #232, AgnesToulet
- Chore: Upgrade grabpl version #231, AgnesToulet
- Add CSV rendering feature #217, AgnesToulet
3.0.0-beta2 (2021-05-26)
- Remove support for plugin V1 protocol #233, AgnesToulet
- Browser: Fix moving CSV file when the tmp folder is not on the same device as the target file path #232, AgnesToulet
- Chore: Upgrade grabpl version #231, AgnesToulet
3.0.0-beta1 (2021-05-19)
- Add CSV rendering feature #217, AgnesToulet
2.1.1 (2021-05-18)
- Chore: Add changelog in package files #226, AgnesToulet
2.1.0 (2021-05-11)
- Chore/Security: Upgrade dependencies and bump Node to LTS (14.16.1) #218, AgnesToulet
2.0.1 (2021-01-26)
- Browser: Use timeout parameter for initial navigation to the dashboard being rendered #171,
2.0.0 (2020-05-16)
- Plugin: Migrate to @grpc/grpc-js to resolve problems when IPv6 is disabled #135, aknuds1
- Adds support for new Grafana backend plugin system #128, marefr
- Browser: Adds support for setting viewport device scale factor #128, marefr
- Browser: Adds support for attaching Accept-Language header to support render is name locale as Grafana user #128, marefr
- Browser: Fail render if the URL has socket protocol #127, aknuds1
- Chore: Upgrade typescript dependencies #129, marefr
2.0.0-beta1 (2020-04-22)
- Adds support for new Grafana backend plugin system #128, marefr
- Browser: Adds support for setting viewport device scale factor #128, marefr
- Browser: Adds support for attaching Accept-Language header to support render is name locale as Grafana user #128, marefr
- Browser: Fail render if the URL has socket protocol #127, aknuds1
- Chore: Upgrade typescript dependencies #129, marefr
1.0.12 (2020-03-31)
- Remote rendering: Delete temporary file after serving it to client #120, marefr
- Remote rendering: More configuration options #123, marefr
1.0.12-beta1 (2020-03-30)
1.0.11 (2020-03-20)
- Render: Add support for enabling verbose logging using environment variable #105, marefr
- Render: Fix panel titles should not be focused when rendering #114, AgnesToulet
- Security: Upgrade minimist dependency to v1.2.5 #118, marefr
1.0.10 (2020-02-18)
1.0.9 (2020-01-30)
- Remote rendering: Improve error handling, logging and metrics #92, marefr
- Service: Don't swallow exceptions and fix logging of parameters
- Metrics: Use status 499 when client close the connection
- Docker: Set NODE_ENV=production
- Changed request logging to use debug level if status < 400 and error if >= 400
- Plugin: Adds icon #95, marefr
1.0.8 (2020-01-20)
- Build: Upgrade Node.js requirement to LTS (v12) #57, marefr
- Docker: Add unifont font to support rendering other language, like Chinese/Japanese #75, okhowang
- Subscribing to page events to catch errors from browser #88, marefr
- Plugin: Automatically assign grpc port per default #87, marefr
- Plugin: Support configuring default timezone thru environment variable #86, marefr
- Remote rendering: Support configuring default timezone thru config file and environment variable #86, marefr
- Remote rendering: Support configuring HTTP host and port thru config and environment variables #40, marefr
- Remote rendering: Support reading config from file #73, marefr
- Remote rendering: Collect and expose Prometheus metrics #71, marefr
Breaking changes
- Plugin now automatically assigns gPRC port not in use. Before port
50059
was used. You can change this by using theGF_RENDERER_PLUGIN_GRPC_PORT
environment variable.
1.0.8-beta1 (2019-12-17)
- Remote rendering: Collect and expose Prometheus metrics #71, marefr
- Build: Upgrade Node.js requirement to LTS (v12) #57, marefr
1.0.7 (2019-12-03)
- Provide correctly named config parameter to Chromium when overriding to skip https errors using environment variable
GF_RENDERER_PLUGIN_IGNORE_HTTPS_ERRORS
and/orIGNORE_HTTPS_ERRORS
#62, marefr
1.0.6 (2019-11-25)
- Wait until all network connections to be idle before rendering #24, d1ff
- Support ignoring https errors using environment variable #59, marefr
- Docker: Update dependencies to remove vulnerabilities #53, marefr
- Fix typo in log statement #39, ankon
- Updated documentation
1.0.5 (2019-09-11)
- Include md5 checksums in release artifacts
1.0.4 (2019-09-11)
- Update readme and docs
1.0.3 (2019-09-10)
- Automate docker release
1.0.2 (2019-09-10)
- Don't include dist directory in archive (zip) files
1.0.1 (2019-09-09)
- Switch docker base image from node:10 to node:alpine-10 #36, marefr
- Updated the panel render wait function to account for Grafana version 6 #26, bmichaelis
- Updated dependencies
1.0.0 (2019-08-16)
Initial release containing prebuilt binaries available for download. Right now the binaries themselves should be considered alpha as they need more testing.