Managing Multiple Environments with Embedded Metabase Dashboard

Luthfi Hariz
ITMI Engineering
Published in
3 min readSep 2, 2020

--

We agree that Metabase is an awesome open-source tool for data crunching and visualization. We use it quite a lot and embed several Questions and Dashboards in our internal tools.

However, a nightmare comes true when you need to make the deployment. By default, Metabase does not come out with a solution in managing multiple environments.

Problem

For example, when we have a web app that embeds Metabase, and that web app has multiple environments connecting to different databases, we find it frustrating every time we want to promote changes in Metabase from one environment to another, let say when you want to deploy from development server to staging server.

What you have to do is creating multiple Questions or Dashboards per environment, and you need to rework your changes every time you want to promote to a different environment.

That is frustrating and a lot of human error can happen. We try to find solutions on the internet but haven’t found any concrete solutions for that.

We almost decided to ditch Metabase and create our own view in React.js and of course, integrated with Git. With proper branching, you don’t have to worry about deployment. But of course, there will be a high cost for maintaining it.

Continue searching on the internet and we found that Metabase comes with a pretty comprehensive Rest API. Basically the API let you CRUD some of the resources, such /questions /dashboard, etc. Here is the doc explaining how to use it.

Solution

We ended up creating an open-source script that took advantage of the Metabase Rest API. With this approach:

  • Each environment represent by one collection
  • All environments, except production, will be in a single Metabase instance.

Under one Metabase instance, we have development, staging, and sandbox collections. Every time we want to promote updates for every Questions and Dashboard will use this script.

node app.js update — origin=[question_id] — dest=[question_id] — databaseId=[database_id]

Let say we want to promote new changes in development to staging, we insert question id at development as origin, and question id at staging as dest. Since development and staging will use different databases, so we need to provide database id for staging.

How to get question id and database id?

To get a question id you only need to see the URL of it.

https://yourmetabase.domain.com/question/827

827 is the question id.

The same thing for database id, whenever you browse data and pick each database you will see its id.

https://yourmetabase.domain.com/browse/11

11 is the database id.

How to promote new Questions?

While the previous script will work for updating Questions, it does not handle promoting new Questions. So we have another command:

node app.js duplicate — questionId=[question_id] — collectionId=[collection_id] — name=[name] — databaseId=[database_id]

Let say we want to promote new Questions in development to staging, we insert question id at development as questionId and collection id for staging as collectionId. And of course, database id for staging.

Name is optional here, in case you want to have a different name.

Work In Progress

This is something that we just start working, so there is still a lot of limitation on it. Things that we would like to have in the near feature are:

  • Updating and duplicating Dashboard. Currently, it only works for Questions.
  • Updating and duplicating between Metabase instance. Currently, it only works under one Metabase instance.

And yes, as we promise above we made it open source. So any kind of contribution will be appreciated.

--

--

Luthfi Hariz
ITMI Engineering

Eight plus years experienced software engineers with two years as engineering lead. Several times involved in building engineering team from scratch.