
简介面向内网或离线环境中需要快速搭建数据可视化平台的企业与开发者这一压缩包提供了 Superset 4.1.1 中文版的 Docker 离线部署方案。它将开源数据探索工具与容器化优势相结合省去联网拉取镜像和英文文档查阅成本中文界面也明显降低了使用门槛。整包共 6 个文件以 tar 镜像文件为主体覆盖 Superset 中文应用、Redis 缓存与 PostgreSQL 数据库三个离线镜像同时包含 docker-compose.yml 容器编排文件、superset_config.py 配置文件和 .env 环境变量文件分别用于服务定义、数据库连接与安全参数设置。压缩包约 524.2MB结构简明适合直接导入部署。目前已有 364 人学习下载。按编排文件启动容器后即可获得可用的中文 Superset 实例可用于企业数据探索、可视化看板搭建与内部 BI 场景也有助于运维人员在无外网环境下理解镜像、编排和配置之间的配合关系。1. Superset 4.1.1 中文版 Docker 离线部署内网 BI 的最后一公里卡在镜像和语言上一个没有外网的数据中心里业务方急着要看板服务器不能连公网手上只有一台能上网的办公电脑。这时候 Apache Superset 4.1.1 的 Docker 离线部署就成了刚需把官方镜像打包运进内网再配好中文界面和数据库驱动整套 BI 环境就能在内网跑起来。这件事难倒过不少人但拆开看只有三个核心问题镜像怎么运进去、中文怎么真正生效、额外的数据库驱动怎么装。本方案就是解决这三个问题的适合做数据平台、数据仓库交付、或者在企业内网搭自助分析环境的工程师。按下面步骤走一到两天内能出一个稳定跑在 4.1.1 上的中文版 Superset。2. 离线部署先从镜像说起save/load 与内网镜像分发的三种做法2.1 有网机器上拉取镜像并固化先核对 tag 再动手离线部署第一步不是写配置而是把 Docker 镜像做成一个可以搬运的文件。我一般会在有网的机器上先拉取apache/superset:4.1.1注意 tag 一定要写全。很多人在这步就翻车拉了个latest回来进内网之后发现行为和预期不一致想排查都没法复现。# 在有网机器上执行 docker pull apache/superset:4.1.1 # 确认镜像存在且架构正确 docker images | grep superset这里docker pull之后用docker images看一眼确认 REPOSITORY 列是apache/supersetTAG 列是4.1.1。如果目标服务器是 ARM 架构比如鲲鹏、飞腾还需要在拉取时指定平台参数否则运过去装上也跑不起来。常见做法是加--platform linux/amd64或--platform linux/arm64取决于你内网服务器的 CPU 架构。确认无误后把镜像固化成本地文件docker save -o superset_4.1.1.tar apache/superset:4.1.1 # 传输前检查文件完整性 ls -lh superset_4.1.1.tardocker save做的事情是把镜像的所有层打包成一个 tar 文件这个文件可以拷贝到 U 盘、通过 scp 或内网文件服务器传进隔离网络。我习惯在 save 完之后立刻记录一下文件大小和 SHA256 值传输完成后比对避免内网传输工具丢数据。镜像本身很大是正常的别因为文件大就怀疑打包失败。如果你用的内网文件服务器经常断点续传失败建议分割传输或者用 rsync 这类带校验的工具。2.2 进内网的通道docker save / docker load 与私有仓库怎么选镜像文件进来之后目标服务器上执行docker load就能把镜像导进本地 Docker。这是最直接的通道适合只有一两台服务器的场景。但如果内网里有十台机器都要部署 Superset每台都docker load一次虽然可行却不是最高效的办法。# 目标服务器执行 docker load -i superset_4.1.1.tar # 验证镜像已经导入 docker images | grep superset另一种更工程化的做法是在内网搭一个私有 registry比如 Harbor 或 Docker Registry把 tar 包 load 到一台机器上之后docker tag再docker push到内网 registry其他机器直接docker pull。这样做的优点在于后续升级镜像版本、分发其他组件时整套流程都能复用不用每次拿 U 盘跑来跑去。如果内网环境规划里有 Kubernetes那更要把镜像放进私有仓库因为 K8s 节点本身是不允许随意从外网拉镜像的。这块没有绝对的对错我的判断标准很简单两到三台机器用 save/load 就够了超过三台直接上私有 registry 更省事。国内很多团队在内网里同时跑 Hadoop、人大金仓数据库、Kodbox 这类私有化组件镜像管理早晚要做不如一开始就选好。2.3 你自己写还是用官方 Compose离线场景下我推荐哪种Superset 官方发布时带了一份 Docker Compose 编排文件分 dev 和 non-dev 两个版本。但离线环境里直接用官方非 dev 版有一个很实际的问题它里面定义的初始化容器和 worker 容器在离线场景下依赖的镜像 tag 比较多搬运起来麻烦而且启动顺序对新手不友好。我一般会在离线部署时写一个精简版 docker-compose.yml只保留 superset 主服务把 worker 和 beat 先砍掉。对于中小团队的分析场景单容器跑 Superset 完全够用后续要扩展再补 worker 也不迟。services: superset: image: apache/superset:4.1.1 container_name: superset restart: always ports: - 8088:8088 environment: - SUPERSET_SECRET_KEYplease_change_this_to_your_own_key - TZAsia/Shanghai volumes: - ./superset_config.py:/app/pythonpath/superset_config.py:ro - superset_home:/app/superset_home volumes: superset_home:这段编排里重点说明三个地方。第一SUPERSET_SECRET_KEY必须改成你自己的随机字符串否则每次重启容器时 session 失效用户会被频繁踢下线。第二./superset_config.py以只读方式挂载到/app/pythonpath/目录这是 Superset 镜像约定的配置目录只要这个文件存在容器启动时就会自动加载。第三superset_home这个命名卷用来持久化 SQLite 数据库和上传的文件资源不挂的话容器一删全没了。这个文件要随镜像一起拷贝进内网我习惯把它和 config 文件放在同一个目录里方便维护。3. 把 4.1.1 调成中文版语言、时区与初始化一个都不能少3.1 中文不生效的真正原因浏览器语言判断与 config.py 的优先级很多人以为 Superset 支持中文就是在界面上选一下语言实际进去后发现只有登录框旁边的语言下拉菜单里能看到中文选项选完也确实是中文。但默认情况下Superset 的界面语言是跟随浏览器 Accept-Language 走的。如果你的内网用户用的是 Chrome 默认英文环境或者公司统一推送了英文版浏览器配置打开 Superset 依然是英文界面。要让 Superset 4.1.1 默认就是中文需要在挂载的superset_config.py里显式指定默认语言而不是依赖用户手工去切。下面这一段是我实际用的配置# -*- coding: utf-8 -*- # superset_config.py 挂载到 /app/pythonpath/ 后自动生效 # 语言配置把中文放在第一位并设置默认 LANGUAGES { zh: {flag: cn, name: Chinese}, en: {flag: us, name: English}, } # 默认界面语言设置为中文 BABEL_DEFAULT_LOCALE zh BABEL_DEFAULT_FOLDER superset/translations配置里的关键是BABEL_DEFAULT_LOCALE这一项决定了用户在未登录和没有显式设置语言偏好时界面默认用哪种语言。LANGUAGES字典则控制语言下拉菜单里能选哪些语言。这里要提醒一句不要只设LANGUAGES不设BABEL_DEFAULT_LOCALE那样下拉菜单里有中文但默认还是英文等于没配。BABEL_DEFAULT_FOLDER保持默认路径不要动指向的是镜像内翻译文件的位置。挂载方式在上一章的 docker-compose.yml 里已经写了把这份文件保存为superset_config.py和 compose 文件放在同一个目录。修改配置后需要重启容器才能生效docker compose restart superset即可不需要重新导入镜像。3.2 第一次启动的初始化顺序db upgrade、create-admin 与 init 连着做镜像导入、容器启动之后Superset 还不能直接用。4.1.1 的镜像默认带了一个空数据库结构需要执行三条初始化命令顺序不能乱。先说结论再解释为什么。# 进入容器执行初始化 docker compose exec superset superset db upgrade docker compose exec superset superset fab create-admin \ --username admin \ --firstname admin \ --lastname admin \ --email adminexample.com \ --password admin123456 docker compose exec superset superset initsuperset db upgrade负责把数据库表结构升级到当前版本对应的 schema。如果你是新建部署这一步就是建表如果你是从旧版本升级上来的这一步会自动跑迁移脚本。第二步superset fab create-admin创建管理员账号这里用的fab命令是 Flask-AppBuilder 的命令行工具Superset 的权限体系构建在它之上。第三步superset init会写入基础角色、权限和默认配置数据不执行这一步的话就算有管理员账号也看不到菜单项。这三条命令我见过很多人跳步骤。有人忘了跑init结果登录进去侧边栏只有空壳有人顺序颠倒先建账号再 upgrade结果账号写进去又被迁移脚本重置。稳妥做法是第一条命令执行完看到日志输出 no problem 或迁移成功字样再执行下一条。整个初始化过程在离线环境里不需要联网所有依赖都在镜像内部。3.3 时区、连接串与编码让图表里的时间不差八小时中文界面搞定之后通常紧跟着的问题是时区。Superset 默认用 UTC 时间国内团队看到的图表时间永远比北京时间慢八小时。这个不是 bug是设计使然需要在两个层面同时处理。第一层是操作系统和运行时的时区在 docker-compose.yml 的 environment 里加TZAsia/Shanghai这样容器内日志时间和执行计划都走北京时间。第二层是在superset_config.py里加一段配置让 Superset 在渲染图表时也按指定时区处理时间字段# 时区配置影响图表时间展示 TIMEZONE Asia/Shanghai但真正隐藏的坑在数据库连接串上。如果你的数据源是 MySQL 或 PostgreSQL连接串里建议显式指定时区和字符集否则数据库返回的 DATETIME 会被 Superset 当作 UTC 处理。常见做法是在连接串后面追加参数mysql://user:passwordmysql_host:3306/your_db?charsetutf8mb4这里charsetutf8mb4是为了让中文数据正常显示不变成乱码。PostgreSQL 的驱动一般在连接串里用options-c%20timezone%3DAsia%2FShanghai的方式指定。这些细节如果不提前处理做出来的图表时间对不上业务方第一反应就是平台有问题解释成本很高。4. 离线装数据库驱动用自定义镜像而不是进容器 pip install4.1 为什么容器内 pip install 是伪需求Superset 产品本身支持连接主流数据库但镜像内置的驱动并不全。默认镜像里带了 PostgreSQL 和 MySQL 的基础驱动可当你需要连接国产数据库或者新版本的 MySQL 8.0 时进容器执行pip install是很多人的第一反应。这在有网环境没问题重启容器后镜像一重建就全没了。离线环境下容器内根本没有网pip install直接报错。更麻烦的是 Superset 镜像的底层是基于特定版本 Python 编译的你在宿主机上手动下载的 wheel 包很可能因为 manylinux 标签不匹配装不上。所以唯一可靠的方式是在有网环境里构建一个包含额外驱动的自定义镜像再把这个镜像 save 进内网分发。这本质上是把“装驱动”这件事提前到打包阶段解决。4.2 在有网机器上用 pip download 攒离线 wheels再 Dockerfile 构建具体做法分两步。第一步拉一个和线上环境一致的 Superset 4.1.1 镜像用容器内的 pip 把需要的驱动下载成 wheel 文件# 在有网机器执行下载驱动到本地 wheels 目录 docker run --rm -v $PWD/wheels:/wheels apache/superset:4.1.1 \ pip download pymysql cryptography -d /wheels这里把当前目录的wheels文件夹挂载到容器里在容器内执行pip download的好处是下载的 wheel 包和 Superset 镜像里的 Python 版本、系统库完全匹配。pymysql是纯 Python 的 MySQL 驱动兼容性最好cryptography是连接 MySQL 8.0 时做认证加密的依赖很多人漏掉它导致连库时报错。下载完成后wheels目录里会有一堆.whl文件。第二步写一个 Dockerfile 把这些 wheel 打进新镜像# 以官方镜像为基础 FROM apache/superset:4.1.1 # 拷贝离线 wheel 包进镜像 COPY wheels /tmp/wheels # 离线安装驱动装完清理临时目录 RUN pip install --no-index --find-links/tmp/wheels \ pymysql cryptography \ rm -rf /tmp/wheels构建命令是docker build -t superset-custom:4.1.1 .。之后流程回到第二章把superset-custom:4.1.1这个新镜像 save 成 tar 包传进内网再 load。构建自定义镜像这个能力后面接人大金仓数据库、达梦数据库时也用得上原理一样只是换驱动包名。4.3 替换镜像后重启config 与驱动生效的验证自定义镜像导入内网后把之前 docker-compose.yml 里的image字段改成新镜像名然后重新创建容器# 目标服务器上执行 docker compose up -d # 看启动日志确认没有报错 docker compose logs superset | tail -n 50判断驱动是否生效最直接的方式是在 Superset 的“数据”菜单里新建数据库连接。填完 MySQL 连接串后Superset 有个测试连接按钮。如果你点了测试依然报Cant connect to MySQL server先看报错是网络层还是认证层。网络层的问题大概率是两台机器不在同一个 Docker 网络里可以用docker network inspect排查认证层的报错通常比网络层多一行caching_sha2_password关键字那就是驱动兼容问题。我见过不少团队在这一步卡两三天最后发现只是 compose 文件里忘了把数据库地址写成容器网络内可达的主机名。记住一个原则Superset 容器访问 MySQL不要写localhost要写 MySQL 容器名或宿主机内网 IP。5. Superset 4.1.1 离线部署避坑五个高频问题的现象与处理5.1 镜像 load 成功 Compose 却找不到镜像tag 对不上现象docker load -i superset_4.1.1.tar执行完没有任何报错docker images也能看到记录但执行docker compose up -d时提示image not found。原因compose 文件里写的镜像名带了:latest后缀比如写成apache/superset:latest而 save 的时候保存的是apache/superset:4.1.1。Docker 不会自动把 4.1.1 当成 latest。解决save 之前先明确 tag或者在 compose 里严格写apache/superset:4.1.1。我习惯把镜像 tag 写进 compose 文件不依赖latest这种可变标签。内网环境里一旦有两个版本的镜像latest指向谁完全不可控。5.2 容器起来但页面一直 loading资源没起来和内存不够是两码事现象浏览器打开 8088 端口登录页能出来但登录之后页面转圈菜单和图表一直不出来。docker compose ps看到容器状态是 Up日志里也没有 fatal 错误。原因这个报错在 4.x 版本里常见。一种情况是superset init没执行权限数据没生成前端请求接口 403 导致白屏另一种情况是容器内存太小Superset 渲染页面时前端资源加载超时。这两者的表现几乎一样但处理方式完全不同。解决先执行docker compose exec superset superset init完成后刷新页面。如果还白屏看宿主机内存和容器日志我一般会给 Superset 容器留至少 2GB 内存在 compose 里用mem_limit: 2g限制。多数 4.1.1 部署的现场问题都是内存不够而不是程序坏了。5.3 切了中文还是英文Accept-Language 与 LANGUAGES 的配合现象config.py 里 LANGUAGES 和 BABEL_DEFAULT_LOCALE 都写了重启后界面还是英文。原因Superset 的语言选择逻辑是先看用户偏好再看浏览器 Accept-Language 头最后才落到默认配置。公司统一安装的浏览器如果默认发en-US且用户在 Superset 用户信息里已经设置过语言偏好那 config 里的默认值就不生效。还有一种情况是挂载的 config.py 没有真正加载容器的/app/pythonpath/路径挂载失败。解决进入容器验证 config 有没有加载docker compose exec superset python -c from superset_config import *; print(BABEL_DEFAULT_LOCALE)能输出zh就是加载了。确认加载后让用户点右上角头像在用户信息里把语言切到中文这是一次性的。想彻底解决就要求内网统一浏览器策略或者干脆接受第一次登录手动切语言。5.4 连接 MySQL 卡在认证插件caching_sha2_password 的兼容处理现象数据库连接测试报错日志里有Authentication plugin caching_sha2_password cannot be loaded或类似字样。原因MySQL 8.0 默认认证插件是caching_sha2_password而 Superset 4.1.1 镜像里自带的 MySQL 客户端驱动对这个插件的支持不完整。这个问题在有网环境也常见离线环境里因为没法顺手升级驱动更容易卡住。解决按第四章方式构建自定义镜像把pymysql和cryptography打进镜像同时把数据库连接串的驱动一层写成mysqlpymysql。我一般建议不要为了图省事把 MySQL 用户的认证插件改成mysql_native_password那是拿数据库安全性妥协不值得。5.5 重启后数据全丢SQLite 与挂载卷的关系现象容器重建之后登录页能打开但之前建的看板、数据源、用户全没了像是新装的一样。原因Superset 默认使用 SQLite 数据库文件存放在容器内部的/app/superset_home目录。这个目录如果没挂载到宿主机容器一删数据就跟着没了。docker-compose.yml 里没写 volumes 的人十有八九踩这个坑。解决在 compose 里配置 volumes把/app/superset_home映射到宿主机目录比如./superset_home_data:/app/superset_home。如果内网已经规划了 MySQL 作为元数据库那就提前在 config.py 里把 SQLAlchemy URI 指过去生产环境更稳。记住SQLite 适合验证和轻量使用多人协作的团队直接上 MySQL 或 PostgreSQL。6. 部署完成后的验证清单与一条保命习惯部署完成不是看一眼页面能打开就结束了我每次交付后都会走一遍固定验证流程。先把服务状态和健康检查跑一遍# 目标服务器上执行验证 docker compose ps # 健康检查接口返回 OK 代表服务正常 curl -s http://localhost:8088/health健康检查通过后用管理员账号登录新建一个测试数据源随便跑一个 Table 类型的图表确认查询、渲染、导出三个路径都通。很多人只验证到图表能出来就收工了导出 Excel 这个功能经常在离线环境里因为字体缺失导出乱码或者直接失败。既然业务方会用到导出就顺手验证掉。这里我想说一个自己吃亏换来的保命习惯每次改 config.py 或 docker-compose.yml 之前先备份当前能用的版本用cp加时间戳就行或者干脆把这个目录纳入 git 管理。离线环境里没有外网出了问题想查资料都费劲唯一可靠的办法就是随时能回滚到上一个能跑的状态。我见过同事手滑把系统自带的 superset_config.py 覆盖了整个平台的登录和权限全部失控最后花了一天才从镜像里扒出原始文件。所以我现在任何配置改动前都留一个备份这个习惯在离线环境里救了我很多次。希望这篇部署笔记能让你少走弯路按这个流程来的话Superset 4.1.1 中文版在内网跑起来只是时间问题。部署完成之后再研究一下自定义图表插件和定时报表这套平台就能真正承担起团队的自助分析需求了。本文还有配套的精品资源点击获取