Metabase の初回セットアップをブラウザなしでやる

2021-03-23

はじめに

CI などコマンドベースで自動化された環境で Metabase が動いている状況を再現したい場合、 ブラウザからの操作なしで初回フローを乗り越える必要があります。

Postgres などを Docker で使う際には、環境変数を設定することで superuser を初期化できるようなコンセプトがありますが、 Metabase には今のところ見当たらないため、どうするか、という話を書きます。

どうするか

結論から言うと Metabase が提供する API を使います。 API Document を見てみると、POST /api/setup という endpoint があり、これを叩けば良さそうです。

列挙されたパラメータの中に token というものがあります。Metabase が初回起動時に内部で生成してバックエンドの DB の setting テーブルに保存している UUID のことです。

説明が Token does not match the setup token. となっていてわかりにくいですが、 API のエラーメッセージ を間違えてコピペしてしまった気配がします。

トークンの入手についてはだいぶ前の issue で解決されていたものがそのまま使えて、 GET /api/session/properties を叩けばいろんな設定情報と一緒に降って来ます。 どこかのバージョンでレスポンス中の対応するキーが setup_token から setup-token に変更になっているので注意が必要です。

情報が揃ったので API にリクエストしてみると、エラーが返ってきます。

% curl -X POST 'http://127.0.0.1:3000/api/setup' \
    -H 'Content-Type: application/json' \
    -d '{ "token": "YOUR_TOKEN", "first_name": "test", "last_name": "test", "site_name": "Metabase", "email": "test@example.com", "password": "hello-m3tab@se" }'
# => {"errors":{"site_name":"value must be a non-blank string."}}

対応するテストを見ると、想定されているリクエストボディの構造がドキュメントの記載とは違うのがわかりました。

// expected
{
  "token": "token",
  "prefs": {
    "site_name": "metabase"
  },
  "user": {
    "first_name": "test",
    "last_name": "test",
    "email": "test@example.com",
    "password": "hello-m3tab@se"
  }
}

正しい構造でリクエストし直して、 Session ID が返ってくれば成功です。

% curl -X POST 'http://127.0.0.1:3000/api/setup' \
    -H 'Content-Type: application/json' \
    -d '{ "token": "YOUR_TOKEN", "user": { "first_name": "test", "last_name": "test", "email": "test@example.com", "password": "hello-m3tab@se" }, "prefs": { "site_name": "Metabase" } }'
# => {"id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}