I was looking for a solution to quickly deploy Grafana to Heroku. The Grafana-Documentation talks about installing it on a Unix-, Linux- or Windows-Server which was not an option for me, because I wanted to use the simple and low cost serverless service from Heroku without maintaining my own server instance. There is a Docker-image available on Dockerhub and that's exactly what we're going to use.
Deploying Grafana with Docker to Heroku:
Deploying Grafana with Docker to Heroku is a bit cumbersome, because Grafana runs on port 3000 by default but Heroku opens a random port on every dyno (re-)start. If we don't change the port, grafana won't connect to the open port and the dyno will crash.
So we need to find a way to override the default port.
Grafana has an environment-variable for this occassion which comes in just handy:
GF_SERVER_HTTP_PORT
Due to the nature of Heroku you cannot just set a fixed number here, so setting it as config variable in heroku is not an option. So we need to extend the existing docker-image.
Extending the Docker-Image:
We will need to extend the existing Docker image with a custom Entrypoint-script to make sure we can set the Port before executing Grafana.
Create a new Folder
grafana
and create the following files in that folder:
mkdir ~/grafana
cd ~/grafana
touch Dockerfile
touch start-grafana.sh
Let's first start with our entrypoint-script. Open
start-grafana.sh
and paste the following contents to it:
#!/bin/bash
# Configure Grafana to use the Heroku-assigned port
export GF_SERVER_HTTP_PORT=$PORT
# Start Grafana
exec grafana server --homepath=/usr/share/grafana
This script sets the necessary environment variable to the Heroku-assigned port and then starts the grafana server.
Open the
Dockerfile
and paste the following contents to it:
FROM grafana/grafana
USER root
COPY start-grafana.sh /start-grafana.sh
RUN chmod +x /start-grafana.sh
ENTRYPOINT ["/start-grafana.sh"]
This creates a new Docker image based on the default grafana-image. It will also copy our entrypoint script to the image and sets it as - well, you've guessed it - entrypoint.
Deploying the extended image to Heroku
Login to Heroku via CLI:
heroku login
Create your new App:
heroku create [app-name]
Set the heroku buildpack
heroku buildpacks:set heroku-community/docker -a [app-name]
Login to Heroku Container Registry to allow your Heroku CLI to interact with Heroku's container registry:
heroku container:login
Push the extended image to heroku:
heroku container:push web -a [app-name]
Release the image to your dyno
heroku container:release web -a [app-name]
Check your logs with heroku logs --tail -a [app-name]
, you should see a lot of log output, but also something like this pretty close to the end of the output:
... msg="HTTP Server Listen" address=[::]:51081 protocol=http ...
The part that's interesting is the "address". It shows the heroku assigned port number, here 51081
, instead of the default port 3000.
You should now be able to access Grafana withheroku open -a [app-name]
or by opening your app in the browser.
Congratulations that was it, Grafana should be running on your Heroku Dyno now.
Extra: Persisting Data & Configuring Grafana
Herokus Filesystems are ephemeral, which means, everything is gone, once the Dyno restarts. To persist your data, you should do some more configuration, like adding an external database:
Database Configuration: If required, set up an external database and configure it through Heroku's environment variables.
(Optional) Set Environment Variables: Configure necessary environment variables via the Heroku CLI or dashboard.
Thanks for reading, I hope it helped you!