From 2484b24c757ef33c847614e71b50bb772346178a Mon Sep 17 00:00:00 2001 From: Marcus Efraimsson Date: Thu, 21 Nov 2019 18:05:26 +0100 Subject: [PATCH] Docker: Custom dockerfiles, docker and image rendering docs update (#20492) Adds support for using custom dockerfiles to pre-install image renderer plugins. Updates docs for docker and image rendering. Fixes #20241 Co-Authored-By: Leonard Gram --- .../sources/administration/image_rendering.md | 108 ++++++++++++++++-- docs/sources/installation/docker.md | 105 +++++++++++------ docs/sources/installation/requirements.md | 2 +- docs/sources/installation/upgrading.md | 8 +- packaging/docker/build-enterprise.sh | 2 +- packaging/docker/build.sh | 2 +- packaging/docker/custom/Dockerfile | 23 ++++ packaging/docker/custom/ubuntu.Dockerfile | 41 +++++++ .../{Dockerfile.ubuntu => ubuntu.Dockerfile} | 0 9 files changed, 245 insertions(+), 46 deletions(-) create mode 100644 packaging/docker/custom/ubuntu.Dockerfile rename packaging/docker/{Dockerfile.ubuntu => ubuntu.Dockerfile} (100%) diff --git a/docs/sources/administration/image_rendering.md b/docs/sources/administration/image_rendering.md index b7b1e9d442c..d5e0ce9240c 100644 --- a/docs/sources/administration/image_rendering.md +++ b/docs/sources/administration/image_rendering.md @@ -17,19 +17,22 @@ When an image is being rendered the PNG-image is temporary written to the filesy A background job runs each 10 minutes and will remove temporary images. You can configure how long time an image should be stored before being removed by configuring the [temp-data-lifetime](/installation/configuration/#temp-data-lifetime) setting. +## Requirements + +Rendering images may require quite a lot of memory, mainly because there are "browser instances" started in the +background responsible for the actual rendering. Further, if multiple images are being rendered in parallel it most +certainly has a bigger memory footprint. Minimum free memory recommendation is 1GB. + +Depending on [rendering method](#rendering-methods) you would need that memory available in the system where the +rendering process is running. For [Grafana Image renderer plugin](#grafana-image-renderer-plugin) and [PhantomJS](#phantomjs) +it's the system which Grafana is installed on. For [Remote rendering service](#remote-rendering-service) it is the system where +that's installed. + ## Rendering methods -### PhantomJS - -> PhantomJS is deprecated since Grafana v6.4 and will be removed in a future release. Please migrate to Grafana image renderer plugin or remote rendering service. - -[PhantomJS](https://phantomjs.org/) have been the only supported and default image renderer since Grafana v2.x and is shipped with Grafana. - -Please note that for macOS and Windows, you will need to ensure that a phantomjs binary is available under tools/phantomjs/phantomjs. For Linux, a phantomjs binary is included - however, you should ensure that any required libraries, e.g. libfontconfig1, are available. - ### Grafana image renderer plugin -> This plugin currently does not work if it is installed in Grafana docker image. +> This plugin currently does not work if it is installed in the Grafana docker image. See [Install in Grafana docker image](#install-in-grafana-docker-image). The [Grafana image renderer plugin](https://grafana.com/grafana/plugins/grafana-image-renderer) is a plugin that runs on the backend and handles rendering panels and dashboards as PNG-images using headless chrome. @@ -39,7 +42,13 @@ You can install it using grafana-cli: grafana-cli plugins install grafana-image-renderer ``` -For further information and instructions refer to the [plugin details](https://grafana.com/grafana/plugins/grafana-image-renderer). +For further information and instructions refer to [troubleshooting](#troubleshooting) and the [plugin details](https://grafana.com/grafana/plugins/grafana-image-renderer). + +#### Install in Grafana docker image + +This plugin is not compatible with the current Grafana Docker image without installing further system-level dependencies. We recommend setting up another Docker container for rendering and using remote rendering, see [Remote rendering service](#remote-rendering-service) for reference. + +If you still want to install the plugin in the Grafana docker image we provide instructions for how to build a custom Grafana image, see [Installing using Docker](/installation/docker/#custom-image-with-grafana-image-renderer-plugin-pre-installed). ### Remote rendering service @@ -102,7 +111,86 @@ callback_url = http://localhost:3000/ ``` 4. Restart Grafana +For further information and instructions refer to [troubleshooting](#troubleshooting) and the [plugin details](https://grafana.com/grafana/plugins/grafana-image-renderer). + +### PhantomJS + +> PhantomJS is deprecated since Grafana v6.4 and will be removed in a future release. Please migrate to Grafana image renderer plugin or remote rendering service. + +[PhantomJS](https://phantomjs.org/) have been the only supported and default image renderer since Grafana v2.x and is shipped with Grafana. + +PhantomJS binaries are included for Linux (x64), Windows (x64) and Darwin (x64). For Linux you should ensure that any required libraries, e.g. libfontconfig1, are available. + +Please note that PhantomJS binaries are not included for ARM. To support this you will need to ensure that a phantomjs binary is available under tools/phantomjs/phantomjs. + ## Alerting and render limits Alert notifications can include images, but rendering many images at the same time can overload the server where the renderer is running. For instructions of how to configure this, see [concurrent_render_limit](/installation/configuration/#concurrent-render-limit). +## Troubleshooting + +Enable debug log messages for rendering in the Grafana configuration file and inspect the Grafana server log. + +```bash +[log] +filters = rendering:debug +``` + +### Grafana image renderer plugin and remote rendering service + +The plugin and rendering service uses [Chromium browser](https://www.chromium.org/) which depends on certain libraries. +If you don't have all of those libraries installed in your system you may encounter errors when trying to render an image, e.g. + +```bash +Rendering failed: Error: Failed to launch chrome!/var/lib/grafana/plugins/grafana-image-renderer/chrome-linux/chrome: +error while loading shared libraries: libX11.so.6: cannot open shared object file: No such file or directory\n\n\nTROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md +``` + +In general you can use the [`ldd`](https://en.wikipedia.org/wiki/Ldd_(Unix)) utility to figure out what shared libraries +are missing/not installed in your system: + +```bash +$ cd +$ ldd chrome-linux/chrome + linux-vdso.so.1 (0x00007fff1bf65000) + libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f2047945000) + libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f2047924000) + librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f204791a000) + libX11.so.6 => not found + libX11-xcb.so.1 => not found + libxcb.so.1 => not found + libXcomposite.so.1 => not found + ... +``` + +**Ubuntu:** + +On Ubuntu 18.10 the following dependencies have been confirmed as needed for the image rendering to function. + +```bash +libx11-6 libx11-xcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrender1 libxtst6 libglib2.0-0 libnss3 libcups2 libdbus-1-3 libxss1 libxrandr2 libgtk-3-0 libgtk-3-0 libasound2 +``` + +**Centos:** + +On a minimal Centos install the following dependencies have been confirmed as needed for the image rendering to function. + +```bash +libXcomposite libXdamage libXtst cups libXScrnSaver pango atk adwaita-cursor-theme adwaita-icon-theme at at-spi2-atk at-spi2-core cairo-gobject colord-libs dconf desktop-file-utils ed emacs-filesystem gdk-pixbuf2 glib-networking gnutls gsettings-desktop-schemas gtk-update-icon-cache gtk3 hicolor-icon-theme jasper-libs json-glib libappindicator-gtk3 libdbusmenu libdbusmenu-gtk3 libepoxy liberation-fonts liberation-narrow-fonts liberation-sans-fonts liberation-serif-fonts libgusb libindicator-gtk3 libmodman libproxy libsoup libwayland-cursor libwayland-egl libxkbcommon m4 mailx nettle patch psmisc redhat-lsb-core redhat-lsb-submod-security rest spax time trousers xdg-utils xkeyboard-config +``` + +#### Using custom Chrome/Chromium + +As a last resort, if you already have [Chrome](https://www.google.com/chrome/) or [Chromium](https://www.chromium.org/) +installed on your system you can configure [Grafana Image renderer plugin](#grafana-image-renderer-plugin) to use this +instead of the pre-packaged version of Chromium. + +> Please note that this is not recommended since you may encounter problems if the installed version of Chrome/Chromium is not +> is compatible with the [Grafana Image renderer plugin](#grafana-image-renderer-plugin). + +To override the path to the Chrome/Chromium executable you can set an environment variable and make sure that +it's available for the Grafana process, e.g. + +```bash +export GF_RENDERER_PLUGIN_CHROME_BIN="/usr/bin/chromium-browser" +``` diff --git a/docs/sources/installation/docker.md b/docs/sources/installation/docker.md index 41d5952b986..444e2824da4 100644 --- a/docs/sources/installation/docker.md +++ b/docs/sources/installation/docker.md @@ -25,8 +25,7 @@ variables by using the syntax `GF__`. For example: ```bash -$ docker run \ - -d \ +$ docker run -d \ -p 3000:3000 \ --name=grafana \ -e "GF_SERVER_ROOT_URL=http://grafana.server.name" \ @@ -53,32 +52,49 @@ GF_PATHS_LOGS | /var/log/grafana GF_PATHS_PLUGINS | /var/lib/grafana/plugins GF_PATHS_PROVISIONING | /etc/grafana/provisioning +## Image Variants + +The official Grafana Docker image comes in two variants. + +**`grafana/grafana:`:** + +> **Note:** This image was based on [Ubuntu](https://ubuntu.com/) before version 6.4.0. + +This is the default image. This image is based on the popular [Alpine Linux project](http://alpinelinux.org), available in [the alpine official image](https://hub.docker.com/_/alpine). Alpine Linux is much smaller than most distribution base images, and thus leads to slimmer and more secure images. + +This variant is highly recommended when security and final image size being as small as possible is desired. The main caveat to note is that it does use [musl libc](http://www.musl-libc.org) instead of [glibc and friends](http://www.etalabs.net/compare_libcs.html), so certain software might run into issues depending on the depth of their libc requirements. However, most software doesn't have an issue with this, so this variant is usually a very safe choice. + +**`grafana/grafana:-ubuntu`:** + +> **Note:** This image is available since version 6.5.0. + +This image is based on [Ubuntu](https://ubuntu.com/), available in [the ubuntu official image](https://hub.docker.com/_/ubuntu). +This is an alternative image for those who prefer an [Ubuntu](https://ubuntu.com/) based image and/or who are dependent on certain +tooling not available for Alpine. + ## Running a specific version of Grafana ```bash -# specify right tag, e.g. 5.1.0 - see Docker Hub for available tags -$ docker run \ - -d \ - -p 3000:3000 \ - --name grafana \ - grafana/grafana:5.1.0 +# specify right tag, e.g. 6.5.0 - see Docker Hub for available tags +$ docker run -d -p 3000:3000 --name grafana grafana/grafana:6.5.0 +# ubuntu based images available since Grafana 6.5.0 +$ docker run -d -p 3000:3000 --name grafana grafana/grafana:6.5.0-ubuntu ``` ## Running the master branch -For every successful build of the master branch we update the `grafana/grafana:master` tag and create a new tag `grafana/grafana-dev:master-` with the hash of the git commit that was built. This means you can always get the latest version of Grafana. +For every successful build of the master branch we update the `grafana/grafana:master` and `grafana/grafana:master-ubuntu`. Additionally, two new tags are created, `grafana/grafana-dev:master-` and `grafana/grafana-dev:master--ubuntu`, which includes the hash of the git commit that was built. This means you can always get the latest version of Grafana. When running Grafana master in production we **strongly** recommend that you use the `grafana/grafana-dev:master-` tag as that will guarantee that you use a specific version of Grafana instead of whatever was the most recent commit at the time. -For a list of available tags, check out [grafana/grafana](https://hub.docker.com/r/grafana/grafana/tags/) and [grafana/grafana-dev](https://hub.docker.com/r/grafana/grafana-dev/tags/). +For a list of available tags, check out [grafana/grafana](https://hub.docker.com/r/grafana/grafana/tags/) and [grafana/grafana-dev](https://hub.docker.com/r/grafana/grafana-dev/tags/). ## Installing Grafana plugins Pass the plugins you want installed to docker with the `GF_INSTALL_PLUGINS` environment variable as a comma separated list. This will pass each plugin name to `grafana-cli plugins install ${plugin}` and install them when Grafana starts. ```bash -docker run \ - -d \ +docker run -d \ -p 3000:3000 \ --name=grafana \ -e "GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource" \ @@ -87,25 +103,49 @@ docker run \ > If you need to specify the version of a plugin, you can add it to the `GF_INSTALL_PLUGINS` environment variable. Otherwise, the latest will be assumed. For example: `-e "GF_INSTALL_PLUGINS=grafana-clock-panel 1.0.1,grafana-simple-json-datasource 1.3.5"` -## Building a custom Grafana image with pre-installed plugins +## Building a custom Grafana image -In the [grafana-docker](https://github.com/grafana/grafana/tree/master/packaging/docker) there is a folder called `custom/` which includes a `Dockerfile` that can be used to build a custom Grafana image. It accepts `GRAFANA_VERSION` and `GF_INSTALL_PLUGINS` as build arguments. +In the [Grafana GitHub repository](https://github.com/grafana/grafana/tree/master/packaging/docker) there is a folder called `custom/` which two includes Dockerfiles, `Dockerfile` and `ubuntu.Dockerfile`, that can be used to build a custom Grafana image. +It accepts `GRAFANA_VERSION`, `GF_INSTALL_PLUGINS` and `GF_INSTALL_IMAGE_RENDERER_PLUGIN` as build arguments. + +### With pre-installed plugins + +> If you need to specify the version of a plugin, you can add it to the `GF_INSTALL_PLUGINS` build argument. Otherwise, the latest will be assumed. For example: `--build-arg "GF_INSTALL_PLUGINS=grafana-clock-panel 1.0.1,grafana-simple-json-datasource 1.3.5"` Example of how to build and run: ```bash cd custom -docker build -t grafana:latest-with-plugins \ +docker build \ --build-arg "GRAFANA_VERSION=latest" \ - --build-arg "GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource" . + --build-arg "GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource" \ + -t grafana-custom -f Dockerfile . -docker run \ - -d \ - -p 3000:3000 \ - --name=grafana \ - grafana:latest-with-plugins +docker run -d -p 3000:3000 --name=grafana grafana-custom ``` -> If you need to specify the version of a plugin, you can add it to the `GF_INSTALL_PLUGINS` build argument. Otherwise, the latest will be assumed. For example: `--build-arg "GF_INSTALL_PLUGINS=grafana-clock-panel 1.0.1,grafana-simple-json-datasource 1.3.5"` +Replace `Dockerfile` in above example with `ubuntu.Dockerfile` to build a custom Ubuntu based image (Grafana 6.5+). + +### With Grafana Image Renderer plugin pre-installed + +> Only available in Grafana v6.5+ and experimental. + +The [Grafana Image Renderer plugin](/administration/image_rendering/#grafana-image-renderer-plugin) does not +currently work if it is installed in Grafana docker image. +You can build a custom docker image by using the `GF_INSTALL_IMAGE_RENDERER_PLUGIN` build argument. +This will install additional dependencies needed for the Grafana Image Renderer plugin to run. + +Example of how to build and run: +```bash +cd custom +docker build \ + --build-arg "GRAFANA_VERSION=latest" \ + --build-arg "GF_INSTALL_IMAGE_RENDERER_PLUGIN=true" \ + -t grafana-custom -f Dockerfile . + +docker run -d -p 3000:3000 --name=grafana grafana-custom +``` + +Replace `Dockerfile` in above example with `ubuntu.Dockerfile` to build a custom Ubuntu based image. ## Installing plugins from other sources @@ -114,8 +154,7 @@ docker run \ It's possible to install plugins from custom url:s by specifying the url like this: `GF_INSTALL_PLUGINS=;` ```bash -docker run \ - -d \ +docker run -d \ -p 3000:3000 \ --name=grafana \ -e "GF_INSTALL_PLUGINS=http://plugin-domain.com/my-custom-plugin.zip;custom-plugin" \ @@ -125,8 +164,7 @@ docker run \ ## Configuring AWS credentials for CloudWatch Support ```bash -$ docker run \ - -d \ +$ docker run -d \ -p 3000:3000 \ --name=grafana \ -e "GF_AWS_PROFILES=default" \ @@ -152,12 +190,7 @@ Supported variables: docker volume create grafana-storage # start grafana -docker run \ - -d \ - -p 3000:3000 \ - --name=grafana \ - -v grafana-storage:/var/lib/grafana \ - grafana/grafana +docker run -d -p 3000:3000--name=grafana -v grafana-storage:/var/lib/grafana grafana/grafana ``` ## Grafana container using bind mounts @@ -249,6 +282,14 @@ chown -R root:root /etc/grafana && \ chown -R grafana:grafana /usr/share/grafana ``` +## Migration from a previous version of the docker container to 6.4 or later + +Grafana’s docker image was changed to be based on [Alpine](http://alpinelinux.org) instead of [Ubuntu](https://ubuntu.com/). + +## Migration from a previous version of the docker container to 6.5 or later + +Grafana Docker image now comes in two variants, one [Alpine](http://alpinelinux.org) based and one [Ubuntu](https://ubuntu.com/) based, see [Image Variants](#image-variants) for details. + ## Logging in for the first time To run Grafana open your browser and go to http://localhost:3000/. 3000 is the default HTTP port that Grafana listens to if you haven't [configured a different port](/installation/configuration/#http-port). diff --git a/docs/sources/installation/requirements.md b/docs/sources/installation/requirements.md index 73ef680bf3b..4ead5fdb119 100644 --- a/docs/sources/installation/requirements.md +++ b/docs/sources/installation/requirements.md @@ -33,7 +33,7 @@ Grafana does not use a lot of resources and is very lightweight in use of memory Depending on what features are being used and to what extent the requirements varies. Features that consume and requires more resources: -- Server side rendering of images +- [Server side rendering of images](/administration/image_rendering/#requirements) - [Alerting](/alerting/rules/) - Data source proxy diff --git a/docs/sources/installation/upgrading.md b/docs/sources/installation/upgrading.md index df2126d9028..f83b8e230d9 100644 --- a/docs/sources/installation/upgrading.md +++ b/docs/sources/installation/upgrading.md @@ -196,9 +196,15 @@ is `7.0+` and `max concurrent shard requests` properly configured. 256 was the d ## Upgrading to v6.4 +### Annotations database migration + One of the database migrations included in this release will merge multiple rows used to represent an annotation range into a single row. If you have a large number of region annotations the database migration may take a long time to complete. See [Upgrading to v5.2](#upgrading-to-v5-2) for tips on how to manage this process. -Plugins that need updating: +### Docker + +Grafana’s docker image is now based on [Alpine](http://alpinelinux.org) instead of [Ubuntu](https://ubuntu.com/). + +### Plugins that need updating - [Splunk](https://grafana.com/grafana/plugins/grafana-splunk-datasource) diff --git a/packaging/docker/build-enterprise.sh b/packaging/docker/build-enterprise.sh index 4fca560c46a..7070f9d2157 100755 --- a/packaging/docker/build-enterprise.sh +++ b/packaging/docker/build-enterprise.sh @@ -31,7 +31,7 @@ if [ ${UBUNTU_BASE} = "0" ]; then DOCKERFILE="Dockerfile" else TAG_SUFFIX="-ubuntu" - DOCKERFILE="Dockerfile.ubuntu" + DOCKERFILE="ubuntu.Dockerfile" fi echo "Building and deploying ${_docker_repo}:${_grafana_tag}${TAG_SUFFIX}" diff --git a/packaging/docker/build.sh b/packaging/docker/build.sh index fc522ae012b..890154c4087 100755 --- a/packaging/docker/build.sh +++ b/packaging/docker/build.sh @@ -63,7 +63,7 @@ docker_build () { base_image="${base_arch}alpine:3.10" else libc="" - dockerfile="Dockerfile.ubuntu" + dockerfile="ubuntu.Dockerfile" base_image="${base_arch}ubuntu:18.10" fi diff --git a/packaging/docker/custom/Dockerfile b/packaging/docker/custom/Dockerfile index 79eba5f29e9..476b7e28887 100644 --- a/packaging/docker/custom/Dockerfile +++ b/packaging/docker/custom/Dockerfile @@ -2,8 +2,31 @@ ARG GRAFANA_VERSION="latest" FROM grafana/grafana:${GRAFANA_VERSION} +USER root + +ARG GF_INSTALL_IMAGE_RENDERER_PLUGIN="false" + +RUN if [ $GF_INSTALL_IMAGE_RENDERER_PLUGIN = "true" ]; then \ + echo "http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories && \ + echo "http://dl-cdn.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories && \ + echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories && \ + apk --no-cache upgrade && \ + apk add --no-cache udev ttf-opensans chromium && \ + rm -rf /tmp/* && \ + rm -rf /usr/share/grafana/tools/phantomjs; \ +fi + USER grafana +ENV GF_RENDERER_PLUGIN_CHROME_BIN="/usr/bin/chromium-browser" + +RUN if [ $GF_INSTALL_IMAGE_RENDERER_PLUGIN = "true" ]; then \ + grafana-cli \ + --pluginsDir "$GF_PATHS_PLUGINS" \ + --pluginUrl https://github.com/grafana/grafana-image-renderer/releases/latest/download/plugin-linux-x64-glibc-no-chromium.zip \ + plugins install grafana-image-renderer; \ +fi + ARG GF_INSTALL_PLUGINS="" RUN if [ ! -z "${GF_INSTALL_PLUGINS}" ]; then \ diff --git a/packaging/docker/custom/ubuntu.Dockerfile b/packaging/docker/custom/ubuntu.Dockerfile new file mode 100644 index 00000000000..2aab4d3e3eb --- /dev/null +++ b/packaging/docker/custom/ubuntu.Dockerfile @@ -0,0 +1,41 @@ +ARG GRAFANA_VERSION="latest-ubuntu" + +FROM grafana/grafana:${GRAFANA_VERSION}-ubuntu + +USER root + +# Set DEBIAN_FRONTEND=noninteractive in environment at build-time +ARG DEBIAN_FRONTEND=noninteractive + +ARG GF_INSTALL_IMAGE_RENDERER_PLUGIN="false" + +RUN if [ $GF_INSTALL_IMAGE_RENDERER_PLUGIN = "true" ]; then \ + apt-get update && \ + apt-get upgrade -y && \ + apt-get install -y chromium-browser && \ + apt-get autoremove -y && \ + rm -rf /var/lib/apt/lists/* && \ + rm -rf /usr/share/grafana/tools/phantomjs; \ +fi + +USER grafana + +ENV GF_RENDERER_PLUGIN_CHROME_BIN="/usr/bin/chromium-browser" + +RUN if [ $GF_INSTALL_IMAGE_RENDERER_PLUGIN = "true" ]; then \ + grafana-cli \ + --pluginsDir "$GF_PATHS_PLUGINS" \ + --pluginUrl https://github.com/grafana/grafana-image-renderer/releases/latest/download/plugin-linux-x64-glibc-no-chromium.zip \ + plugins install grafana-image-renderer; \ +fi + +ARG GF_INSTALL_PLUGINS="" + +RUN if [ ! -z "${GF_INSTALL_PLUGINS}" ]; then \ + OLDIFS=$IFS; \ + IFS=','; \ + for plugin in ${GF_INSTALL_PLUGINS}; do \ + IFS=$OLDIFS; \ + grafana-cli --pluginsDir "$GF_PATHS_PLUGINS" plugins install ${plugin}; \ + done; \ +fi diff --git a/packaging/docker/Dockerfile.ubuntu b/packaging/docker/ubuntu.Dockerfile similarity index 100% rename from packaging/docker/Dockerfile.ubuntu rename to packaging/docker/ubuntu.Dockerfile