diff --git a/Dockerfile b/Dockerfile index df049a80..6e4a5896 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,24 +1,38 @@ -FROM debian:jessie +FROM debian:stretch-slim -ARG DOWNLOAD_URL="https://s3-us-west-2.amazonaws.com/grafana-releases/master/grafana_latest_amd64.deb" +ARG GRAFANA_URL="https://s3-us-west-2.amazonaws.com/grafana-releases/master/grafana-latest.linux-x64.tar.gz" +ARG GF_UID="472" +ARG GF_GID="472" -RUN apt-get update && \ - apt-get -y --no-install-recommends install libfontconfig curl ca-certificates && \ - apt-get clean && \ - curl ${DOWNLOAD_URL} > /tmp/grafana.deb && \ - dpkg -i /tmp/grafana.deb && \ - rm /tmp/grafana.deb && \ - curl -L https://github.com/tianon/gosu/releases/download/1.10/gosu-amd64 > /usr/sbin/gosu && \ - chmod +x /usr/sbin/gosu && \ - apt-get autoremove -y && \ - rm -rf /var/lib/apt/lists/* +ENV PATH=/usr/share/grafana/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ + GF_PATHS_CONFIG="/etc/grafana/grafana.ini" \ + GF_PATHS_DATA="/var/lib/grafana" \ + GF_PATHS_HOME="/usr/share/grafana" \ + GF_PATHS_LOGS="/var/log/grafana" \ + GF_PATHS_PLUGINS="/var/lib/grafana/plugins" \ + GF_PATHS_PROVISIONING="/etc/grafana/provisioning" -VOLUME ["/var/lib/grafana", "/var/log/grafana", "/etc/grafana"] +RUN apt-get update && apt-get install -qq -y tar libfontconfig curl ca-certificates && \ + mkdir -p "$GF_PATHS_HOME/.aws" && \ + curl "$GRAFANA_URL" | tar xfvz - --strip-components=1 -C "$GF_PATHS_HOME" && \ + apt-get autoremove -y && \ + rm -rf /var/lib/apt/lists/* && \ + groupadd -r -g $GF_GID grafana && \ + useradd -r -u $GF_UID -g grafana grafana && \ + mkdir -p "$GF_PATHS_PROVISIONING/datasources" \ + "$GF_PATHS_PROVISIONING/dashboards" \ + "$GF_PATHS_LOGS" \ + "$GF_PATHS_PLUGINS" \ + "$GF_PATHS_DATA" && \ + cp "$GF_PATHS_HOME/conf/sample.ini" "$GF_PATHS_CONFIG" && \ + cp "$GF_PATHS_HOME/conf/ldap.toml" /etc/grafana/ldap.toml && \ + chown -R grafana:grafana "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" && \ + chmod 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" EXPOSE 3000 COPY ./run.sh /run.sh +USER grafana WORKDIR / - -ENTRYPOINT ["/run.sh"] +ENTRYPOINT [ "/run.sh" ] \ No newline at end of file diff --git a/README.md b/README.md index fbaf92d4..1119e945 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![CircleCI](https://circleci.com/gh/grafana/grafana-docker.svg?style=svg)](https://circleci.com/gh/grafana/grafana-docker) -This project builds a Docker image with the latest master build of Grafana. +This project builds a Docker image for Grafana. ## Running your Grafana container @@ -14,7 +14,7 @@ docker run -d --name=grafana -p 3000:3000 grafana/grafana Try it out, default admin user is admin/admin. -In case port 3000 is closed for external clients or you there is no access +In case port 3000 is closed for external clients or there is no access to the browser - you may test it by issuing: curl -i localhost:3000/login Make sure that you are getting "...200 OK" in response. @@ -43,19 +43,23 @@ More information in the grafana configuration documentation: http://docs.grafana ## Grafana container with persistent storage (recommended) ``` -# create /var/lib/grafana as persistent volume storage -docker run -d -v /var/lib/grafana --name grafana-storage busybox:latest +# create a persistent volume for your data in /var/lib/grafana (database and plugins) +docker volume create grafana-storage # start grafana docker run \ -d \ -p 3000:3000 \ --name=grafana \ - --volumes-from grafana-storage \ + -v grafana-storage:/var/lib/grafana \ grafana/grafana ``` -## Installing plugins for Grafana 3 +Note: An unnamed volume will be created for you when you boot Grafana, +using `docker volume create grafana-storage` just makes it easier to find +by giving it a name. + +## Installing plugins for Grafana Pass the plugins you want installed to docker with the `GF_INSTALL_PLUGINS` environment variable as a comma seperated list. This will pass each plugin name to `grafana-cli plugins install ${plugin}`. @@ -70,24 +74,19 @@ docker run \ ## Building a custom Grafana image with pre-installed plugins -Dockerfile: -```Dockerfile -FROM grafana/grafana:5.0.0 -ENV GF_PATHS_PLUGINS=/opt/grafana-plugins -RUN mkdir -p $GF_PATHS_PLUGINS -RUN grafana-cli --pluginsDir $GF_PATHS_PLUGINS plugins install grafana-clock-panel -``` - -Add lines with `RUN grafana-cli ...` for each plugin you wish to install in your custom image. Don't forget to specify what version of Grafana you wish to build from (replace 5.0.0 in the example). +The `custom/` folder includes a `Dockerfile` that can be used to build a custom Grafana image. It accepts `GRAFANA_VERSION` and `GF_INSTALL_PLUGINS` as build arguments. Example of how to build and run: ```bash -docker build -t grafana:5.0.0-custom . +cd custom +docker build -t grafana:latest-with-plugins \ + --build-arg "GRAFANA_VERSION=latest" \ + --build-arg "GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource" . docker run \ -d \ -p 3000:3000 \ --name=grafana \ - grafana:5.0.0-custom + grafana:latest-with-plugins ``` ## Running specific version of Grafana @@ -126,6 +125,9 @@ Supported variables: ## Changelog +### v5.1.0 +* Complete overhaul + ### v4.2.0 * Plugins are now installed into ${GF_PATHS_PLUGINS} * Building the container now requires a full url to the deb package instead of just version diff --git a/build.sh b/build.sh index cc120953..9fc54743 100755 --- a/build.sh +++ b/build.sh @@ -1,22 +1,19 @@ #!/bin/bash -_grafana_tag=$1 -_grafana_version=${_grafana_tag:1} +_grafana_version=$1 _docker_repo=${2:-grafana/grafana} if [ "$_grafana_version" != "" ]; then echo "Building version ${_grafana_version}" - echo "Download url: https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_${_grafana_version}_amd64.deb" docker build \ - --build-arg DOWNLOAD_URL=https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_${_grafana_version}_amd64.deb \ + --build-arg GRAFANA_URL="https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-${_grafana_version}.linux-x64.tar.gz" \ --tag "${_docker_repo}:${_grafana_version}" \ --no-cache=true . docker tag ${_docker_repo}:${_grafana_version} ${_docker_repo}:latest - else echo "Building latest for master" docker build \ --tag "grafana/grafana:master" \ - --no-cache=true . + . fi diff --git a/custom/Dockerfile b/custom/Dockerfile new file mode 100644 index 00000000..79eba5f2 --- /dev/null +++ b/custom/Dockerfile @@ -0,0 +1,16 @@ +ARG GRAFANA_VERSION="latest" + +FROM grafana/grafana:${GRAFANA_VERSION} + +USER grafana + +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/run.sh b/run.sh index 1fe7ecde..df64ce3a 100755 --- a/run.sh +++ b/run.sh @@ -1,16 +1,33 @@ #!/bin/bash -e -: "${GF_PATHS_CONFIG:=/etc/grafana/grafana.ini}" -: "${GF_PATHS_DATA:=/var/lib/grafana}" -: "${GF_PATHS_LOGS:=/var/log/grafana}" -: "${GF_PATHS_PLUGINS:=/var/lib/grafana/plugins}" -: "${GF_PATHS_PROVISIONING:=/etc/grafana/provisioning}" +PERMISSIONS_OK=0 + +if [ ! -r "$GF_PATHS_CONFIG" ]; then + echo "GF_PATHS_CONFIG='$GF_PATHS_CONFIG' is not readable." + PERMISSIONS_OK=1 +fi + +if [ ! -w "$GF_PATHS_DATA" ]; then + echo "GF_PATHS_DATA='$GF_PATHS_DATA' is not writable." + PERMISSIONS_OK=1 +fi + +if [ ! -r "$GF_PATHS_HOME" ]; then + echo "GF_PATHS_HOME='$GF_PATHS_HOME' is not readable." + PERMISSIONS_OK=1 +fi + +if [ $PERMISSIONS_OK -eq 1 ]; then + echo "You may have issues with file permissions, more information here: http://docs.grafana.org/installation/docker/#migration-from-a-previous-version-of-the-docker-container-to-5-1-or-later" +fi + +if [ ! -d "$GF_PATHS_PLUGINS" ]; then + mkdir "$GF_PATHS_PLUGINS" +fi -chown -R grafana:grafana "$GF_PATHS_DATA" "$GF_PATHS_LOGS" || true if [ ! -z ${GF_AWS_PROFILES+x} ]; then - mkdir -p ~grafana/.aws/ - > ~grafana/.aws/credentials + > "$GF_PATHS_HOME/.aws/credentials" for profile in ${GF_AWS_PROFILES}; do access_key_varname="GF_AWS_${profile}_ACCESS_KEY_ID" @@ -18,17 +35,16 @@ if [ ! -z ${GF_AWS_PROFILES+x} ]; then region_varname="GF_AWS_${profile}_REGION" if [ ! -z "${!access_key_varname}" -a ! -z "${!secret_key_varname}" ]; then - echo "[${profile}]" >> ~grafana/.aws/credentials - echo "aws_access_key_id = ${!access_key_varname}" >> ~grafana/.aws/credentials - echo "aws_secret_access_key = ${!secret_key_varname}" >> ~grafana/.aws/credentials + echo "[${profile}]" >> "$GF_PATHS_HOME/.aws/credentials" + echo "aws_access_key_id = ${!access_key_varname}" >> "$GF_PATHS_HOME/.aws/credentials" + echo "aws_secret_access_key = ${!secret_key_varname}" >> "$GF_PATHS_HOME/.aws/credentials" if [ ! -z "${!region_varname}" ]; then - echo "region = ${!region_varname}" >> ~grafana/.aws/credentials + echo "region = ${!region_varname}" >> "$GF_PATHS_HOME/.aws/credentials" fi fi done - chown grafana:grafana -R ~grafana/.aws - chmod 600 ~grafana/.aws/credentials + chmod 600 "$GF_PATHS_HOME/.aws/credentials" fi if [ ! -z "${GF_INSTALL_PLUGINS}" ]; then @@ -36,16 +52,16 @@ if [ ! -z "${GF_INSTALL_PLUGINS}" ]; then IFS=',' for plugin in ${GF_INSTALL_PLUGINS}; do IFS=$OLDIFS - gosu grafana grafana-cli --pluginsDir "${GF_PATHS_PLUGINS}" plugins install ${plugin} + grafana-cli --pluginsDir "${GF_PATHS_PLUGINS}" plugins install ${plugin} done fi -exec gosu grafana /usr/sbin/grafana-server \ - --homepath=/usr/share/grafana \ - --config="$GF_PATHS_CONFIG" \ - "$@" \ - cfg:default.log.mode="console" \ - cfg:default.paths.data="$GF_PATHS_DATA" \ - cfg:default.paths.logs="$GF_PATHS_LOGS" \ - cfg:default.paths.plugins="$GF_PATHS_PLUGINS" \ - cfg:default.paths.provisioning=$GF_PATHS_PROVISIONING +exec grafana-server \ + --homepath="$GF_PATHS_HOME" \ + --config="$GF_PATHS_CONFIG" \ + "$@" \ + cfg:default.log.mode="console" \ + cfg:default.paths.data="$GF_PATHS_DATA" \ + cfg:default.paths.logs="$GF_PATHS_LOGS" \ + cfg:default.paths.plugins="$GF_PATHS_PLUGINS" \ + cfg:default.paths.provisioning="$GF_PATHS_PROVISIONING" \ No newline at end of file