教程:在新的 Metabase 实例中使用序列化预加载仪表板
如何使用 Metabase 的序列化功能将问题、仪表板、集合、设置等从一个 Metabase 实例复制到新的 Metabase 实例。
Metabase 序列化
序列化仅适用于 Pro 和 Enterprise 计划(包括自托管和 Metabase 云服务)。
许多使用 Pro 和 Enterprise 套餐的客户在多租户环境中使用 Metabase,这需要上传预定义的 问题或 仪表板集,以设置新的 Metabase 实例或新的数据库连接。
本文将介绍如何
- 创建一套默认的问题和仪表板。
- 导出这些仪表板。
- 将这些仪表板重新导入到一个新实例。
具体来说,我们将使用 Metabase 序列化功能中的 export 和 import 命令来执行第二和第三步,再加上对导出文件的一些手动整理。
我们将使用 Docker 来运行我们的源 Metabase 和目标 Metabase,并使用 PostgresSQL 作为它们的 应用程序数据库。我们不建议在生产环境中使用默认的 H2 数据库。
虽然本教程使用了 Metabase 的 export 和 import 命令,但您也可以 通过 API 序列化 Metabase 应用程序数据。
计划
我们将创建一个源 Metabase,创建一个仪表板,导出该仪表板,然后将该仪表板导入到一个新的 Metabase(我们的目标)。以下是计划:
- 创建一个名为 metanet 的专用网络.
- 启动两个 Metabase:源和目标.
- 在源 Metabase 中创建仪表板和集合
- 从源 Metabase 导出数据.
- 将源导出导入到目标 Metabase.
- 验证我们的仪表板和集合是否已加载到目标 Metabase 中.
先决条件
您需要 在您的机器上安装 Docker。
步骤 1 - 创建专用网络
要创建一个名为“metanet”的专用网络,请在您选择的终端中运行以下命令:
docker network create metanet
您可以通过运行以下命令来确认网络已被创建:
docker network ls
该网络将具有本地范围和桥接驱动程序。
步骤 2 - 启动两个 Metabase:源和目标
启动两个名为 metabase-source 和 metabase-target 的 Metabase(尽管您可以随意命名这些环境)。请注意,我们在创建这些 Docker 容器时使用了 --rm -d,这样当您停止它们时它们都会被移除并在后台运行。您可以随意更改这些标志来修改该行为。
源 Metabase
创建 Postgres 数据库
docker run --rm -d --name postgres \
-p 5433:5432 \
-e POSTGRES_USER=metabase \
-e POSTGRES_PASSWORD=knockknock \
--network metanet \
postgres:12
创建我们的源 Metabase,并将其连接到我们刚刚创建的 Postgres 数据库
docker run --rm -d --name metabase-source \
-p 5001:3000 \
-e MB_DB_TYPE=postgres \
-e MB_DB_DBNAME=metabase \
-e MB_DB_PORT=5432 \
-e MB_DB_USER=metabase \
-e MB_DB_PASS=knockknock \
-e MB_DB_HOST=postgres \
--network metanet \
metabase/metabase-enterprise:v1.57.7
您可以查看容器日志以了解容器的进度
docker logs metabase-source
一旦您看到包含“Metabase initialization COMPLETE”的行,就可以在浏览器中打开 https://:5001 来查看您的 Metabase 实例。
目标 Metabase
设置目标 Metabase 类似。在我们的 metanet 网络上,我们将设置一个 Postgres 数据库作为我们的应用程序数据库,然后启动另一个 Docker 容器中的 Metabase。
请注意以下更改:
- Postgres (5434) 和 Metabase 服务器 (5002) 的端口
- 实例名称:
postgres-target和metabase-target
应用程序数据库
docker run --rm -d --name postgres-target \
-p 5434:5432 \
-e POSTGRES_USER=metabase \
-e POSTGRES_PASSWORD=knockknock \
--network metanet postgres:12
Metabase 实例
docker run --rm -d --name metabase-target \
-p 5002:3000 \
-e MB_DB_TYPE=postgres \
-e MB_DB_DBNAME=metabase \
-e MB_DB_PORT=5432 \
-e MB_DB_USER=metabase \
-e MB_DB_PASS=knockknock \
-e MB_DB_HOST=postgres-target \
--network metanet \
metabase/metabase-enterprise:v1.57.7
在我们的 Metabase 实例完成初始化后(请耐心等待,可能需要一两分钟),现在应该有两个 Metabase 正在运行:
- metabase-source 位于
https://:5001 - metabase-target 位于
https://:5002
向我们的源 Metabase 添加用户
让我们向 metabase-source 实例添加一个管理员帐户和两个普通用户。
您可以通过应用程序手动 添加 Metabase 用户(即在 Metabase 应用程序中),但这是一个快速 bash 脚本,可创建一个管理员用户(初始用户)和两个普通用户。
您需要 安装 jq 来处理此脚本中的 JSON。
#!/bin/sh
ADMIN_EMAIL=${MB_ADMIN_EMAIL:-admin@metabase.local}
ADMIN_PASSWORD=${MB_ADMIN_PASSWORD:-Metapass123}
METABASE_HOST=${MB_HOSTNAME}
METABASE_PORT=${MB_PORT:-3000}
echo "⌚︎ Waiting for Metabase to start"
while (! curl -s -m 5 http://${METABASE_HOST}:${METABASE_PORT}/api/session/properties -o /dev/null); do sleep 5; done
echo "😎 Creating admin user"
SETUP_TOKEN=$(curl -s -m 5 -X GET \
-H "Content-Type: application/json" \
http://${METABASE_HOST}:${METABASE_PORT}/api/session/properties \
| jq -r '.["setup-token"]'
)
MB_TOKEN=$(curl -s -X POST \
-H "Content-type: application/json" \
http://${METABASE_HOST}:${METABASE_PORT}/api/setup \
-d '{
"token": "'${SETUP_TOKEN}'",
"user": {
"email": "'${ADMIN_EMAIL}'",
"first_name": "Metabase",
"last_name": "Admin",
"password": "'${ADMIN_PASSWORD}'"
},
"prefs": {
"allow_tracking": false,
"site_name": "Metawhat"
}
}' | jq -r '.id')
echo -e "\n👥 Creating some basic users: "
curl -s "http://${METABASE_HOST}:${METABASE_PORT}/api/user" \
-H 'Content-Type: application/json' \
-H "X-Metabase-Session: ${MB_TOKEN}" \
-d '{"first_name":"Basic","last_name":"User","email":"basic@somewhere.com","login_attributes":{"region_filter":"WA"},"password":"'${ADMIN_PASSWORD}'"}'
curl -s "http://${METABASE_HOST}:${METABASE_PORT}/api/user" \
-H 'Content-Type: application/json' \
-H "X-Metabase-Session: ${MB_TOKEN}" \
-d '{"first_name":"Basic 2","last_name":"User","email":"basic2@somewhere.com","login_attributes":{"region_filter":"CA"},"password":"'${ADMIN_PASSWORD}'"}'
echo -e "\n👥 Basic users created!"
将上述代码保存为 create_users.sh,并使其可执行:
chmod +x create_users.sh
然后运行:
MB_HOSTNAME=localhost MB_PORT=5001 ./create_users.sh
在 metabase-source 实例启动且用户创建完成后,打开 https://:5001 并使用您创建的管理员用户登录。用户 ID 是 admin@metabase.local,密码是 Metapass123。
您应该会看到一个全新的 Metabase 实例。

登录后,激活您的许可证密钥。
步骤 3 - 在源 Metabase 中创建仪表板和集合
我们需要一些应用程序数据来导出,因此让我们使用 Metabase 包含的 示例数据库创建一些仪表板。或者,让我们让 Metabase 为我们创建一些仪表板!
在“根据您的数据尝试这些 X-Rays”部分,单击带有黄色闪电图标的卡片,该卡片上显示“A look at Products”等内容。Metabase 将为您生成一组问题,您可以将其保存为仪表板。

单击“保存此”按钮,Metabase 将在名为“A look at Products”的集合中保存仪表板及其问题。
此集合将保存在一个名为 Automatically Generated Dashboards 的父集合中。您可以通过单击导航栏左上角的 Metabase 徽标返回主屏幕来找到此集合。在主页的“我们的分析”部分,单击“Automatically Generated Dashboards”部分。从中您应该可以看到名为 A look at your Products table 的集合。

接下来,创建一个新集合。您可以随意命名;我们将使用一个令人兴奋的名称 Default collection,并将其保存在“我们的分析”集合中。

然后,我们将 A look at Products 集合移动到我们新创建的 Default collection。在 A look at Products 集合页面上,单击省略号…,然后选择“移动”。
步骤 4 - 从源 Metabase 导出
这是我们实际开始使用 Metabase 的 序列化功能的地方。
在设置了包含一些问题的 metabase-source 实例后,现在是时候导出这些数据并将其导入到我们的 metabase-target 中了。这样我们就无需手动在目标 Metabase 中重新创建我们的 Default Collection。
首先,我们在 /tmp 目录中创建一个名为 metabase_data 的目录来存储我们的导出文件。
cd /tmp
mkdir metabase_data
接下来,我们将运行导出命令。
docker run --rm --name metabase-export \
--network metanet \
-e MB_DB_CONNECTION_URI="postgres://postgres:5432/metabase?user=metabase&password=knockknock" \
-v "/tmp/metabase_data:/target" \
metabase/metabase-enterprise:v1.57.7 "export /target"
此命令创建一个名为 metabase-export 的临时 Metabase 实例。此临时 Metabase 将连接到我们源 Metabase 的 Postgres 应用程序数据库,并导出其应用程序数据。
如果一切顺利,几秒钟后您应该会看到一些输出,然后终端会显示一条消息:serialization.cmd :: Export to '/target' complete! 🚛💨 📦
要验证导出,请 cd 进入您的目录:/tmp/metabase_data。您应该会看到两个目录和三个 YAML 文件,例如:
设置
settings 文件包含许多可以在设置新实例时配置的选项。它看起来会像这样:
aggregated-query-row-limit: null
application-colors: null
application-favicon-url: null
application-font: null
application-font-files: null
application-logo-url: null
application-name: null
available-fonts: null
available-locales: null
available-timezones: null
breakout-bins-num: null
custom-formatting: null
custom-geojson: null
custom-geojson-enabled: null
default-maps-enabled: null
enable-embedding: null
enable-nested-queries: null
enable-sandboxes?: null
enable-whitelabeling?: null
enable-xrays: null
hide-embed-branding?: null
humanization-strategy: null
landing-page: null
loading-message: null
native-query-autocomplete-match-style: null
persisted-models-enabled: null
report-timezone: null
report-timezone-long: null
report-timezone-short: null
search-typeahead-enabled: null
show-homepage-data: null
show-homepage-pin-message: null
show-homepage-xrays: null
show-lighthouse-illustration: null
show-metabot: null
show-static-embed-terms: null
site-locale: null
site-name: Metawhat
source-address-header: null
start-of-week: null
subscription-allowed-domains: null
unaggregated-query-row-limit: null
uploads-database-id: null
uploads-enabled: null
uploads-schema-name: null
数据库
此目录包含我们连接的数据库的所有 元数据设置。在这种情况下,我们只有 Metabase 附带的示例数据库。
集合
在 collections 目录中有我们设置的集合、仪表板和问题。eDuYBjvKEwhFg6QxtBziP_default_collection 目录包含子集合和其他项。每个项都以一个代码作为前缀,以避免命名冲突。
这是集合 YAML 文件的一瞥:
name: Default collection
description: null
entity_id: qmJu_4D1gviNjHUCcn978
slug: default_collection
created_at: "2024-03-12T15:01:45.955848Z"
archived: false
type: null
parent_id: null
personal_owner_id: null
namespace: null
authority_level: null
serdes/meta:
- id: qmJu_4D1gviNjHUCcn978
label: default_collection
model: Collection
这是标题为 Products per category 的示例问题(称为卡片)的一瞥:
ame: Products per Category
description: null
entity_id: bnghENFKtgeKRMfU3sF7y
created_at: "2024-03-12T14:59:01.795343Z"
creator_id: admin@metabase.local
display: row
archived: false
collection_id: JI0l2T_O-_EhdAxk2pdin
collection_preview: true
collection_position: null
query_type: query
dataset: false
cache_ttl: null
database_id: Sample Database
table_id:
- Sample Database
- PUBLIC
- PRODUCTS
enable_embedding: false
embedding_params: null
made_public_by_id: null
public_uuid: null
parameters: []
parameter_mappings: []
dataset_query:
database: Sample Database
query:
aggregation:
- - count
breakout:
- - field
- - Sample Database
- PUBLIC
- PRODUCTS
- CATEGORY
- null
source-table:
- Sample Database
- PUBLIC
- PRODUCTS
type: query
result_metadata: null
visualization_settings:
column_settings: null
graph.colors:
- "#EF8C8C"
graph.dimensions:
- CATEGORY
graph.metrics:
- count
graph.series_labels:
- null
serdes/meta:
- id: bnghENFKtgeKRMfU3sF7y
label: products_per_category
model: Card
initially_published_at: null
metabase_version: v1.49.0
type: question
步骤 5 - 导入到目标 Metabase
为了上传导出文件,我们的目标 Metabase 至少需要有一个管理员帐户。您可以直接通过应用程序登录创建该用户,或使用我们上面使用的脚本:只需记住将 MB_PORT 更改为 5002,因为这是我们分配给目标 Metabase 的端口。例如,cd 进入您保存 create_users.sh 脚本的目录,然后运行:
MB_HOSTNAME=localhost MB_PORT=5002 ./create_users.sh
我们可以将所有这些设置上传到目标 Metabase,但假设我们只想导入我们的默认集合。
让我们复制我们的 /tmp/metabase_data 目录,以便我们保留原始内容并对副本进行更改。
cp -r /tmp/metabase_data /tmp/serialize_import
由于每个 Metabase 实例都包含示例数据库,而且我们没有对元数据进行任何更改,因此让我们删除 databases 目录。运行:
rm -r /tmp/serialize_import/databases
要验证更改,您可以使用 diff 命令查看原始 serialized_data 目录和您将用于导入目标 Metabase 的 serialized_load 目录之间的差异。
cd /tmp
diff -r metabase_data serialize_import
您应该会看到以下内容:
Only in metabase_data: databases
在将数据导入目标 Metabase 之前,您需要 激活您的许可证。
现在,在设置好我们的 /tmp/serialize_import 目录后,我们可以运行导入命令将元数据导入到我们的目标 Metabase 中。
docker run --rm --name metabase-export \
--network metanet \
-e MB_DB_CONNECTION_URI="postgres://postgres-target:5432/metabase?user=metabase&password=knockknock" \
-v "/tmp/serialize_import:/target" \
metabase/metabase-enterprise:v1.57.7 "import /target"
步骤 6 - 在目标 Metabase 中验证仪表板和集合
现在,如果您登录到位于 https://:5002 的目标 Metabase,您应该会看到我们的 Default collection 已准备就绪,其中包含我们的 A look at your Products table 集合。
就这样:您已经使用包含仪表板和问题的集合预加载了一个全新的 Metabase 实例!
序列化限制
请注意,序列化转储不包含某些数据:
- 权限设置
- 用户帐户或设置
- 已保存问题的警报
- 个人集合或其内容
通过 API 进行序列化
您还可以通过 API 导入和导出 Metabase 应用程序数据。请参阅 通过 API 序列化 Metabase。通过 API 进行导出和导入对于 Metabase Cloud 实例(您无法访问环境)可能很有用。
序列化的其他用例
使用序列化功能导出问题和仪表板开辟了一些很酷的可能性,包括:
- 为问题和仪表板添加版本控制。您可以将下载的元数据签入到仓库中,并通过 git 等版本控制软件管理该数据。
- 为 Metabase 设置暂存环境。您可以尝试使用暂存环境,直到您对更改满意为止,然后导出元数据,并将其上传到生产环境。
尝试使用序列化功能,并在 我们的论坛上告诉我们您是如何使用它的。