How I use Docker for plugin development

I thought I’d share how I use Docker for developing plugins. Docker makes it really easy for me to test my plugin against multiple versions of Grafana. For example, to make sure that the plugin still works with the earliest supported version of Grafana (as defined by grafanaDependency in plugin.json).

Here’s a one-liner that starts a Docker container running Grafana:

docker run -d \
    -e GF_DEFAULT_APP_MODE=development \
    -p 3000:3000 \
    -v ~/src/github.com/marcusolsson/grafana-plugins:/var/lib/grafana/plugins \
    grafana/grafana:8.3.3
  • -d makes the container run in the background.
  • -e GF_DEFAULT_APP_MODE=development starts Grafana in development mode, which lets me run unsigned plugins.
  • -p 3000:3000 exposes Grafana at port 3000 on my local machine.
  • -v ~/src/github.com/marcusolsson/grafana-plugins:/var/lib/grafana/plugins mounts my plugins in the default plugin directory inside the container.

This lets me develop my plugins for multiple Grafana versions simultaneously. For example, I can run version 8.0.0 on a different port:

docker run -d \
    -e GF_DEFAULT_APP_MODE=development \
    -p 3001:3000 \
    -v ~/src/github.com/marcusolsson/grafana-plugins:/var/lib/grafana/plugins \
    grafana/grafana:8.0.0

Now I can switch between browser tabs to test whether a change introduces a regression!

3 Likes

And while we’re at it, why not add a convenient ZSH helper.

  1. Add the following to your .zshrc file:

    start_plugin_dev() {
      docker run -d \
        -e GF_DEFAULT_APP_MODE=development \
        -p "${2:=3000}:3000" \
        -v ~/src/github.com/marcusolsson/grafana-plugins:/var/lib/grafana/plugins \
        grafana/grafana:"${1:=latest}"
    }
    
  2. In a new terminal, run the function with the latest version of Grafana:

    start_plugin_dev
    
    • start_plugin_dev 8.0.0 to run a specific version.
    • start_plugin_dev 8.0.0 3001 to run a specific version on a specific port.
2 Likes

Cool. I also want to show my setup :sweat_smile:

I have a docker-compose file that I update the version number to test different versions and how my plugin interracts with other plugins.

My docker-compose file:

version: "3"
services:
  grafana-dev:
    image: grafana/grafana:8.3.1
    container_name: grafana
    restart: always
    networks:
      - grafana
    volumes:
      - ./grafana-plugins:/var/lib/grafana/plugins
      - grafana-storage-dev:/var/lib/grafana
    ports:
      - 3100:3000
    environment:
      - GF_APP_MODE=development
      - GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s:%(http_port)s/
      - GF_SERVER_SERVE_FROM_SUB_PATH=true
      - GF_DASHBOARDS_MIN_REFRESH_INTERVAL=0.1s
      - GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS=gapit-htmlgraphics-panel,marcusolsson-json-datasource
      - GF_LIVE_ALLOWED_ORIGINS=*
      - GF_SECURITY_ADMIN_PASSWORD=admin
      - GF_USERS_DEFAULT_THEME=dark
      - GF_INSTALL_PLUGINS=marcusolsson-static-datasource

volumes:
  grafana-storage-dev:

networks:
  grafana:
    external: true
    name: grafana
4 Likes

Nice! :star_struck:

Mounting /var/lib/grafana as a volume is really useful if you want to reuse state. I had this in my earlier configuration, but since I tend to create new dashboard to test things rather than to reuse them, I ended up with a ton of dashboards with gibberish names. I decided I’ll just wipe them until I’ve proved I can handle the responsibility :sweat_smile:.

Also cool to see you’re using the Static plugin!

3 Likes

oooh, this is SLICK!

I have also found these two aliased commands helpful. A quick way to stop and remove all Docker containers:

alias stopc='docker stop $(docker ps -aq)'
alias rmc='docker rm $(docker ps -aq)'
2 Likes

I’ll be stealing these!