Python Runner 部署指南:为 Metabase 自托管 Python 转换配置独立执行环境
【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase
<output_article>
Metabase Python Runner 部署实战:为自托管 Python 转换配置独立执行环境
导读
本文聚焦于 Metabase Data Studio 中 Python 转换(Python transforms)的关键基础设施——Python Runner:一个独立于 Metabase 主实例运行的 Python 代码执行服务。你将掌握如何在自托管场景下,通过 Docker、环境变量或 Docker Compose 完成 Python Runner 与 Metabase 的对接,配置 S3 兼容存储(AWS S3 / MinIO 等)用于传递执行工件,并理解这些配置项在 Metabase 后端源码中的真实语义与默认值。读完本文,你可以独立搭建一套生产可用的 Python 转换执行环境,并能定位常见的"Metabase 连不上 Runner""Runner 连不上存储"类故障。
说明:自托管场景下的 Python 转换需要自托管 Pro 或 Enterprise 计划,并购买 Advanced transforms 附加组件。若使用 Metabase Cloud,则需购买 Transforms 附加组件。Python Runner 的核心机制与配置流程详见 python-runner.md。
一、为什么需要 Python Runner
在了解配置之前,先明确架构背景。Metabase 的转换(Transforms)承担了"ETL 中的 T":运行查询或脚本,在目标数据库建表写入结果,并把新表同步回 Metabase 供提问(Questions)或其他转换复用。转换分两类(见 transforms-overview.md):
- 基于查询的转换(query-based transforms):用 SQL 或查询构建器编写,直接在数据库内执行,无需额外组件;
- Python 转换(Python transforms):用 Python 编写,运行在专门的执行环境中,必须由 Python Runner 提供。
Python 转换的完整工作链路(见 python-transforms.md):
- 在 Metabase 中编写一个返回
pandasDataFrame 的transform()函数,引用一个或多个数据表; - Metabase 启动一个独立的 Python 执行环境(而非在 Metabase 实例内部)运行该脚本;
- Metabase 安全地把源数据复制到 Python 环境,以 pandas DataFrame 形式暴露;
- Python 环境在内存中执行脚本,把结果 DataFrame 保存为文件(工件);
- Metabase 读取该文件,把结果写入目标数据库的新表,并同步该表;
- 后续运行默认覆盖目标表,除非配置了增量转换。
这一"Metabase ↔ Runner ↔ S3 存储"的三方协作正是本文配置工作的核心。从企业版源码 base.clj 可以印证:执行时会调用python-runner/copy-tables-to-s3!把源表复制到 S3,再调用execute-python-code-http-call!让 Runner 执行脚本,随后从 S3 读取输出清单(output manifest)与事件日志,最终把结果写回数据库。因此 Runner 与 Metabase 之间通过HTTP API通信,而数据工件通过S3 兼容存储中转。
二、前置条件
在开始部署前,请确认满足以下条件(python-runner.md):
- 已安装并运行Docker,或具备可运行容器的其他基础设施;
- 持有自托管 Metabase Pro 或 Enterprise 许可证(Python Runner 属于付费能力,Open Source 自托管计划不可用,参见 addons.md);
- 生产环境:准备一个 S3 兼容的存储桶(AWS S3、MinIO 等),并记录访问凭据。
另外请通读 transforms-overview.md 中自托管转换的完整设置路径:检查计划 → 连接可写数据库(转换会创建/替换表,数据库用户需具备 create/drop/write 权限,建议配置 writable connection)→ 为 Python 转换准备 Runner → 在 Data Studio 中启用转换 → 创建并运行转换。
三、快速开始:内置 S3 服务器(仅体验)
最简单的上手方式是使用 Python Runner 镜像自带的内置 S3 服务器(端口 4566)。此模式仅用于试用,不可用于生产(python-runner.md):
# 1. 创建 Docker 网络,使容器之间可以通信 docker network create metabase-network # 2. 启动 Python Runner,并启用内置 S3 docker run -d \ --network metabase-network \ -e AUTH_TOKEN=your-secure-token-here \ -e ENABLE_INTERNAL_S3=true \ --name python-runner metabase/python-runner:latest # 3. 启动 Metabase Enterprise,指向 Runner 与内置 S3 docker run -d \ --network metabase-network \ -p 3000:3000 \ -e MB_PYTHON_RUNNER_URL=http://python-runner:5000 \ -e MB_PYTHON_RUNNER_API_TOKEN=your-secure-token-here \ -e MB_PYTHON_STORAGE_S_3_ENDPOINT=http://python-runner:4566 \ -e MB_PYTHON_STORAGE_S_3_BUCKET=metabase-python-runner \ -e MB_PYTHON_STORAGE_S_3_REGION=us-east-1 \ -e MB_PYTHON_STORAGE_S_3_PATH_STYLE_ACCESS=true \ -e MB_PYTHON_STORAGE_S_3_ACCESS_KEY=test \ -e MB_PYTHON_STORAGE_S_3_SECRET_KEY=test \ --name metabase metabase/metabase-enterprise:latest两个容器必须处于同一 Docker 网络(metabase-network),因为 Metabase 通过容器名python-runner访问 Runner(端口 5000)与内置 S3(端口 4566)。内置 S3 的默认凭据为test/test,仅用于本地体验。
四、生产环境部署步骤
生产环境必须使用外部的 S3 兼容存储服务(python-runner.md),分三步完成:
步骤 1:生成安全的认证令牌
Runner 与 Metabase 之间通过令牌(token)完成 API 鉴权,令牌必须双方一致:
openssl rand -hex 32妥善保存生成的 64 位十六进制字符串,两个容器都会用到它。
步骤 2:准备 S3 存储
在 S3 兼容服务(AWS S3、MinIO 等)中创建一个存储桶,并记下访问密钥(Access Key)与秘密密钥(Secret Key)。注意:Metabase 和 MinIO 都不会自动创建桶,桶必须由你提前创建(下文 Compose 示例中的minio-init容器正是为此存在)。
步骤 3:启动两个容器
docker network create metabase-network # Python Runner(不启用内置 S3) docker run -d \ --network metabase-network \ -e AUTH_TOKEN=your-secure-token-here \ --name python-runner --hostname python-runner metabase/python-runner:latest # Metabase Enterprise(指向外部 S3) docker run -d \ --network metabase-network \ -p 3000:3000 \ -e MB_PYTHON_RUNNER_URL=http://python-runner:5000 \ -e MB_PYTHON_RUNNER_API_TOKEN=<your-secure-token-here> \ -e MB_PYTHON_STORAGE_S_3_ENDPOINT=https://s3.amazonaws.com \ -e MB_PYTHON_STORAGE_S_3_BUCKET=your-bucket-name \ -e MB_PYTHON_STORAGE_S_3_REGION=us-east-1 \ -e MB_PYTHON_STORAGE_S_3_ACCESS_KEY=your-access-key \ -e MB_PYTHON_STORAGE_S_3_SECRET_KEY=your-secret-key \ --name metabase metabase/metabase-enterprise:latest使用 AWS S3 时无需设置MB_PYTHON_STORAGE_S_3_PATH_STYLE_ACCESS(默认关闭,使用虚拟主机式寻址);仅当使用 MinIO、LocalStack 等 S3 兼容服务时才需置为true。
五、配置参考:环境变量全解析
5.1 Python Runner 侧环境变量
| 变量 | 说明 |
|---|---|
AUTH_TOKEN | 用于 API 请求的认证令牌,必须与 Metabase 的MB_PYTHON_RUNNER_API_TOKEN一致 |
ENABLE_INTERNAL_S3 | 设为true时启用内置 S3 服务器(端口 4566),仅用于试用,不适用于生产 |
5.2 Metabase 侧环境变量
这些设置也可以在 Metabase UI 中配置:Admin>Settings>Python Runner。注意:环境变量的优先级高于 UI 设置。
| 变量 | 说明 |
|---|---|
MB_PYTHON_RUNNER_URL | Metabase 访问 Python Runner 的地址(如http://python-runner:5000) |
MB_PYTHON_RUNNER_API_TOKEN | 认证令牌,必须与 Runner 的AUTH_TOKEN一致 |
MB_PYTHON_STORAGE_S_3_ENDPOINT | S3 端点 URL |
MB_PYTHON_STORAGE_S_3_CONTAINER_ENDPOINT | Runner 容器视角看到的 S3 端点;若与主端点不同才需要设置 |
MB_PYTHON_STORAGE_S_3_BUCKET | 存储 Python 工件的 S3 桶名 |
MB_PYTHON_STORAGE_S_3_REGION | AWS 区域(如us-east-1) |
MB_PYTHON_STORAGE_S_3_ACCESS_KEY | S3 访问密钥 |
MB_PYTHON_STORAGE_S_3_SECRET_KEY | S3 秘密密钥 |
MB_PYTHON_STORAGE_S_3_PATH_STYLE_ACCESS | (可选)使用 MinIO 或 LocalStack 等 S3 兼容服务时设为true |
5.3CONTAINER_ENDPOINT的语义
MB_PYTHON_STORAGE_S_3_CONTAINER_ENDPOINT是Metabase 签署进预签名 URL(presigned URLs)的主机名,Runner 通过该 URL 上传与下载工件。当Runner 解析存储服务所用的主机名与 Metabase 不同时,需要设置此项为 Runner 视角的地址(python-runner.md)。
典型场景:Metabase 与 Runner 不在同一网络,Metabase 通过https://s3.amazonaws.com访问 S3,而 Runner 容器内必须通过http://minio:9000才能访问到同一存储——此时ENDPOINT填 Metabase 视角的地址,CONTAINER_ENDPOINT填 Runner 视角的地址,Metabase 会按后者生成 Runner 可访问的预签名 URL。
5.4 源码层面的完整参数清单
从企业版源码 settings.clj 可以看到,Metabase 后端实际定义了比文档表格更完整的设置项,且带有非生产环境默认值(config/is-prod?为假时生效),便于本地开发:
| 源码设置名(对应环境变量) | 类型 | 非生产默认值 | 说明(源码注释) |
|---|---|---|---|
python-runner-url(MB_PYTHON_RUNNER_URL) | string | http://localhost:5001 | 运行 transform 函数的 Python 执行服务器 URL |
python-runner-api-token(MB_PYTHON_RUNNER_API_TOKEN) | string(敏感) | dev-token-12345 | 与 python-runner 服务通信的 API 令牌 |
python-storage-s-3-endpoint(MB_PYTHON_STORAGE_S_3_ENDPOINT) | string | http://localhost:4566 | 存储 Python 执行工件的 S3 端点 |
python-storage-s-3-region(MB_PYTHON_STORAGE_S_3_REGION) | string | us-east-1 | S3 存储区域 |
python-storage-s-3-bucket(MB_PYTHON_STORAGE_S_3_BUCKET) | string | metabase-python-runner | 存储 Python 执行工件的 S3 桶 |
python-storage-s-3-prefix(MB_PYTHON_STORAGE_S_3_PREFIX) | string | test-prefix | S3 对象前缀;生产环境需要设置以限定访问特定前缀 |
python-storage-s-3-access-key(MB_PYTHON_STORAGE_S_3_ACCESS_KEY) | string(敏感) | test | S3 访问密钥 ID |
python-storage-s-3-secret-key(MB_PYTHON_STORAGE_S_3_SECRET_KEY) | string(敏感) | test | S3 秘密访问密钥 |
python-storage-s-3-container-endpoint(MB_PYTHON_STORAGE_S_3_CONTAINER_ENDPOINT) | string | http://localstack:4566 | 容器内可访问的替代 S3 端点;与主端点相同则留空 |
python-storage-s-3-path-style-access(MB_PYTHON_STORAGE_S_3_PATH_STYLE_ACCESS) | boolean | true | 对 S3 请求使用路径式访问(LocalStack 及部分 S3 兼容服务必需) |
python-runner-timeout-seconds | integer | 1800(30 分钟) | Python 脚本执行超时 |
python-runner-test-run-timeout-seconds | integer | 60(1 分钟) | Python 脚本测试运行(预览)超时 |
值得注意的源码细节:
- 敏感项加密:
python-runner-api-token、python-storage-s-3-access-key、python-storage-s-3-secret-key等在设置了加密密钥时会加密存储(encryption :when-encryption-key-set),其中令牌与秘密密钥不参与审计(audit :never); - 特性门控:以上所有设置均标记
feature :transforms-python,即仅在启用 Advanced transforms(Python 转换能力)后生效; - 生产默认值缺失:所有默认值都只在非生产环境生效,生产环境下必须显式提供全部配置,这正是上文"生产部署必须逐项填写环境变量"的源码依据。
5.5 Runner 的 HTTP API 端点
从 python_runner.clj 可以确认 Runner 对外暴露的 HTTP 接口,理解这些端点有助于排查故障:
POST /execute:提交 Python 脚本执行(携带request_id、脚本内容、超时参数等);GET /logs:按request_id获取执行日志;POST /cancel:按request_id取消执行。
其中python-runner-request会携带api-token(来自MB_PYTHON_RUNNER_API_TOKEN)完成鉴权——这就是文档强调"Runner 的AUTH_TOKEN必须与 Metabase 的MB_PYTHON_RUNNER_API_TOKEN一致"的原因。
六、Docker Compose 一键部署(含 MinIO)
生产或长期测试环境推荐使用 Docker Compose 编排全部组件。官方文档提供了一套自托管存储 + MinIO的完整示例(python-runner.md)。
MinIO 是自托管场景下常见的 S3 兼容服务器,与自托管 Metabase 搭配自然。该 Compose 文件同时运行 Metabase、Python Runner、MinIO,以及一个一次性容器minio-init负责创建桶——因为 MinIO 与 Metabase 都不会替你创建桶:
name: metabase-python-runner services: metabase: image: metabase/metabase-enterprise:latest ports: - "3000:3000" environment: - MB_PYTHON_RUNNER_URL=http://python-runner:5000 - MB_PYTHON_RUNNER_API_TOKEN=${AUTH_TOKEN} - MB_PYTHON_STORAGE_S_3_ENDPOINT=http://minio:9000 - MB_PYTHON_STORAGE_S_3_CONTAINER_ENDPOINT=http://minio:9000 - MB_PYTHON_STORAGE_S_3_BUCKET=metabase-python-runner - MB_PYTHON_STORAGE_S_3_REGION=us-east-1 - MB_PYTHON_STORAGE_S_3_PATH_STYLE_ACCESS=true - MB_PYTHON_STORAGE_S_3_ACCESS_KEY=${MINIO_ROOT_USER} - MB_PYTHON_STORAGE_S_3_SECRET_KEY=${MINIO_ROOT_PASSWORD} depends_on: minio-init: condition: service_completed_successfully python-runner: condition: service_started python-runner: image: metabase/python-runner:latest environment: - AUTH_TOKEN=${AUTH_TOKEN} minio: image: quay.io/minio/minio:latest command: server /data --console-address ":9001" environment: - MINIO_ROOT_USER=${MINIO_ROOT_USER} - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD} volumes: - minio-data:/data minio-init: image: quay.io/minio/mc:latest depends_on: minio: condition: service_started entrypoint: - /bin/sh - -c - | until mc alias set local http://minio:9000 "${MINIO_ROOT_USER}" "${MINIO_ROOT_PASSWORD}" >/dev/null 2>&1; do echo "waiting for minio..."; sleep 2; done mc mb --ignore-existing local/metabase-python-runner volumes: minio-data: {}为什么两个 S3 端点变量都指向http://minio:9000?因为 Metabase 与 Runner 共享同一个 Compose 网络,二者以相同主机名访问 MinIO。MB_PYTHON_STORAGE_S_3_CONTAINER_ENDPOINT决定 Metabase 签署进预签名 URL 的主机名——若你的 Runner 与 Metabase 解析存储的主机名不同,应将其设为 Runner 视角的地址。
创建.env文件提供共享凭据:
AUTH_TOKEN=your-secure-token-here MINIO_ROOT_USER=minioadmin MINIO_ROOT_PASSWORD=minioadmin然后按顺序完成验证:
生成强共享密钥(Runner 与 Metabase 必须对同一令牌达成一致):
openssl rand -hex 32启动整个栈:
docker compose up -d启用并运行转换:需要带有 Advanced transforms 附加组件 的 Pro 或 Enterprise 许可证。先在 Metabase 中启用转换,再创建 Python 转换并点击Run。
查看运行结果:打开Data Studio > Jobs > Runs找到本次运行。若运行失败,日志通常会指明故障方向:是 Metabase 无法连接 Runner,还是 Runner 无法连接 MinIO。
七、验证与排障指南
7.1 验证连通性
部署完成后,可通过以下方式快速验证:
- Runner 可达性:在 Metabase 容器内测试
curl http://python-runner:5000(或从宿主机curl http://localhost:5000,若已映射端口),确认 HTTP 服务响应; - S3 可达性:在 Runner 容器内测试对
http://minio:9000的访问(MinIO 场景),确认凭据与桶存在; - 端到端:创建最小 Python 转换并点击Run Python script(编辑器右下角按钮),Metabase 会从每个输入表拉取100 行数据运行预览,可在Results preview标签页查看结果、在Output标签页查看
print()输出。
7.2 常见故障方向
- Metabase 无法连接 Runner:检查
MB_PYTHON_RUNNER_URL是否可从 Metabase 容器解析、AUTH_TOKEN与MB_PYTHON_RUNNER_API_TOKEN是否一致、两容器是否在同一网络; - Runner 无法连接存储:检查
MB_PYTHON_STORAGE_S_3_*系列配置,特别是 MinIO 场景下PATH_STYLE_ACCESS=true与CONTAINER_ENDPOINT是否正确; - 桶不存在:MinIO 与 Metabase 都不会自动建桶,确认
minio-init成功执行(mc mb完成)。
7.3 运行时行为约束(源码佐证)
- Python 转换串行执行:从 settings.clj 的源码注释可以看到,python-runner 服务是单线程的,因此 Python 转换在作业内总是逐个执行(并行派发只会让它们排队并各自触发超时);与之对比,SQL 转换可通过
transform-run-job-sql-concurrency(默认 3)并行执行; - 转换超时:
transform-timeout(默认 240 分钟)控制整个转换作业的超时,优先于常规查询的MB_DB_QUERY_TIMEOUT_MINUTES; - 测试预览超时:
python-runner-test-run-timeout-seconds(默认 60 秒)约束点击Run Python script时的预览执行。
八、生产环境 Checklist
完成部署后,请对照以下清单逐项确认:
- ✅ 使用
openssl rand -hex 32生成强令牌,并确保 Runner 的AUTH_TOKEN与 Metabase 的MB_PYTHON_RUNNER_API_TOKEN完全一致; - ✅ S3 桶已提前创建(MinIO 场景由
minio-init完成),Metabase 与 Runner 均能访问; - ✅ 生产环境显式设置了全部
MB_PYTHON_STORAGE_S_3_*配置(源码默认值仅存在于非生产环境); - ✅ 若 Runner 解析存储的主机名与 Metabase 不同,正确设置了
MB_PYTHON_STORAGE_S_3_CONTAINER_ENDPOINT; - ✅ MinIO / LocalStack 场景设置
MB_PYTHON_STORAGE_S_3_PATH_STYLE_ACCESS=true; - ✅ 已购买 Advanced transforms 附加组件,并在 Data Studio 中启用转换、配置了带写入权限的可写连接;
- ✅ 通过Data Studio > Jobs > Runs验证了一次真实的 Python 转换运行,并检查其日志。
完成以上步骤后,你的 Metabase 即可稳定地承载 Python 转换工作负载。更进一步,可阅读 python-transforms.md 掌握transform()函数编写技巧与增量转换配置,或通过 jobs-and-runs.md 将转换纳入定时调度。 </output_article>
【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考