资讯详情

Superset 4.1.1中文版Docker离线部署全指南:镜像、汉化与避坑

📅 2026/10/12 16:25:26 | 华诺云谱 👁 阅读
Superset 4.1.1中文版Docker离线部署全指南:镜像、汉化与避坑
简介面向需要在隔离网络或离线环境中部署数据可视化平台的企业与开发者提供Superset 4.1.1中文版的Docker一站式离线部署方案。资源共6个文件打包约524.2MB包含Redis、PostgreSQL、Superset等3个tar格式镜像文件以及docker-compose.yml、superset_config.py、.env等关键配置覆盖容器编排、应用配置与环境变量定义无需外网即可完成环境组装。已有364人学习下载适合具有一定Docker基础、希望快速落地中文可视化看板的中高级运维或数据分析人员。借助该包可避开逐一手动构建镜像与配置依赖的繁琐流程直接按既定文件结构启动服务并基于中文界面开展数据探索与图表制作同时内置的配置文件给出常用参数示例便于结合实际调整数据库连接、认证方式等减少试错成本显著提升内网环境下敏捷交付与自主可控的部署效率。1. 先厘清 Superset 4.1.1 离线部署这件事镜像、汉化和内网落地「Superset 4.1.1 中文版 Docker 离线部署」这一串词落到一线就是一句话在一台没有公网的服务器上把 Apache Superset 这个 BI 平台跑起来而且浏览器里打开就是中文界面。很多团队拿着docker save出来的 tar 包就冲结果卡在元数据库连不上、界面老跳英文、示例数据加载必失败这些零碎问题上。真正的难点不在镜像搬运而在初始化链路和运行时依赖是否完整。这份笔记按我从零交付内网 BI 平台的实际路径来写先在联网机上把镜像和离线依赖一次捞全再用 Docker Compose 把服务编排起来把中文界面和时区调好最后落到验证与备份。适合内网交付工程师、数据平台运维以及给客户做私有化部署的乙方同学。2. 联网机上把镜像和依赖一次捞全离线部署的「搬运包」怎么造离线部署的准备工作核心就一条把所有要在内网出现的东西提前在联网机上下载好并以文件形式搬运。Superset 4.1.1 官方镜像是apache/superset:4.1.1它内部已经编译好了前端静态资源也带好了 superset 命令行工具所以镜像本体是必选项。除了主服务我一般会一并准备 PostgreSQL 和 Redis 两个镜像前者放 Superset 自己的元数据库后者放缓存。如果只是本机演示也可以让 Superset 用自带的 SQLite 跑起来省掉两个容器但离线交付大多是长期生产环境不建议省这一步后续做并发和升级时你会感谢当初的坚持。2.1 拉取与导出官方镜像docker pull / save 的最小流程# 在联网机上准备 3 个镜像 mkdir -p /opt/offline_pkg cd /opt/offline_pkg docker pull apache/superset:4.1.1 docker pull postgres:16-alpine docker pull redis:7-alpine # 导出为 tar 存档注意用 仓库名:标签不要用 IMAGE ID docker save -o superset_4.1.1.tar apache/superset:4.1.1 docker save -o postgres_16.tar postgres:16-alpine docker save -o redis_7.tar redis:7-alpine # 压缩后再拷进内网U 盘或共享目录都行 gzip superset_4.1.1.tardocker save导出的是镜像层的归档文件不是容器现状所以导出前不需要启动容器。用仓库名加标签导出才能保证 load 之后 REPOSITORY 和 TAG 保持可读而不是变成none。postgres:16-alpine和redis:7-alpine是常见的小体积配套alpine 系镜像能省不少传输时间。gzip 这一步可做可不做但 Superset 的 tar 包通常 1GB 以上压一下更稳妥拷贝和后续归档都舒服。内网机上恢复其实只有一条命令docker load直接识别 gzip 压缩的 tar不需要先解压# 内网机器上恢复镜像文件名随便镜像标签保持不变 docker load -i superset_4.1.1.tar.gz docker load -i postgres_16.tar docker load -i redis_7.tar # 确认三个镜像都带正确 tag docker imagesload 之后如果docker images里看到apache/superset且 TAG 是4.1.1说明导入成功。这里最容易翻车的是 save 时手滑用了 IMAGE ID导致 load 后没有 tag后面 docker compose 里写了指定的镜像名找不到标签会直接报错。注意如果内网服务器是 ARM 或者国产化 CPU这一步请换到同架构的联网机上执行。x86 上打包的镜像搬到 ARM 机器上是跑不起来的这是离线部署里成本最高的一次返工。2.2 自定义镜像把数据库驱动和离线 wheel 打进 superset 基础镜像官方apache/superset镜像只带基础能力连 MySQL 数据源时你会发现没有 pymysql 驱动。内网环境又无法现场pip install所以正确姿势是联网机上用 Dockerfile 扩展一个 superset-local 镜像把驱动直接打进去再 save 这个本地镜像。所有连接外部数据源需要的 SQLAlchemy 方言都必须在 superset 进程的 Python 环境里装到宿主机上是没有任何作用的。先准备一个 Dockerfile# Dockerfile.superset-local FROM apache/superset:4.1.1 USER root # wheels 是上一步在联网机下载的离线包与镜像内 Python 版本严格匹配 COPY wheels /tmp/wheels RUN pip install --no-index --find-links/tmp/wheels \ pymysql \ psycopg2-binary \ rm -rf /tmp/wheels USER superset这段的关键有两处。第一FROM 后面直接接apache/superset:4.1.1保证和线上镜像同源第二USER root是必须的官方镜像默认用 superset 用户运行没有权限往系统 Python 环境里写包装完再切回 superset避免容器启动时因权限问题崩溃。--no-index表示不走 PyPI--find-links只从 wheels 目录里找如果内网构建这一步还去访问外网源说明离线准备没做干净。最后构建并导出这个本地镜像docker build -f Dockerfile.superset-local -t superset-local:4.1.1 . docker save -o superset-local_4.1.1.tar superset-local:4.1.1 gzip superset-local_4.1.1.tar构建在联网机上执行因为基础镜像apache/superset:4.1.1需要先在联网机拉下来。如果基础镜像已存在构建过程本身不会再访问网络真正不可控的是 pip 步骤所以 wheels 目录一定要打包随行不能只把 Dockerfile 带到内网。2.3 离线 wheel 包的正确做法先探明镜像内 Python 版本再 pip download这一节专门讲 wheels 目录怎么来。很多教程让你在宿主机上pip download一堆包但 Superset 镜像内部的 Python 版本和宿主机往往不一致二进制 wheel 装进去立刻报invalid ELF header或者cannot import name。所以先跑一条命令把镜像里的 Python 版本问清楚docker run --rm apache/superset:4.1.1 python --version # 输出例如 Python 3.11.x就找同版本的解释器下载 python3.11 -m pip download -d wheels pymysql psycopg2-binarypip download只下载不安装它和pip install使用同一套依赖解析规则所以下载下来的文件直接当成离线源是安全的。下载完检查 wheels 目录后缀应该是 .whl文件名里带 cp311 和 manylinux 之类的兼容标记如果出现 .tar.gz 源码包说明这个平台的预编译 wheel 不存在装进镜像时大概率现场编译失败趁早换一个功能等价的纯 Python 包比如把 mysqlclient 换成 pymysql。把整个离线包的清单整理出来后面按单核验就行| 对象 | 用途 | 准备方式 | | apache/superset:4.1.1 | Superset 主服务镜像 | docker pull save | | superset-local:4.1.1 | 加了数据库驱动的扩展镜像 | docker build save | | postgres:16-alpine | 元数据库镜像 | docker pull save | | redis:7-alpine | 缓存镜像 | docker pull save | | wheels 目录 | 离线 pip 源 | pip download 后打包 |我习惯把整包结构固定成一个目录放镜像 tar 包、一个 wheels 目录、一份说明文档。到内网后先验 docker 引擎和磁盘空间再 load 镜像再跑初始化后面的事就相对机械了。3. 用 Docker Compose 编排 Superset 4.1.1服务定义、初始化命令与启动顺序到了内网机第一步不是急着 up而是先确认离线机上有没有 docker compose 插件。很多服务器只装了 docker 引擎compose 插件被省了输入docker compose version直接报 command not found。这种情况下要么离线安装 compose 插件要么退回单容器docker run方案我建议前者因为 Compose 把网络、健康检查、卷、环境变量固化成一个文件后续升级和排障都依赖这份文件。3.1 最小可用的 docker-compose.ymlsuperset postgres redisservices: superset: image: superset-local:4.1.1 # 用 2.2 构建的本地镜像不是官方镜像 container_name: superset restart: unless-stopped ports: - 8088:8088 environment: SUPERSET_SECRET_KEY: please-change-me SUPERSET_CONFIG_PATH: /app/superset_config.py TZ: Asia/Shanghai volumes: - ./superset_config.py:/app/superset_config.py:ro - superset_home:/app/superset_home depends_on: postgres: condition: service_healthy redis: condition: service_healthy healthcheck: test: [CMD, python, -c, import urllib.request; urllib.request.urlopen(http://127.0.0.1:8088/health)] interval: 30s timeout: 10s retries: 5 start_period: 90s postgres: image: postgres:16-alpine environment: POSTGRES_USER: superset POSTGRES_PASSWORD: superset POSTGRES_DB: superset volumes: - pg_data:/var/lib/postgresql/data healthcheck: test: [CMD-SHELL, pg_isready -U superset -d superset] interval: 10s timeout: 5s retries: 10 redis: image: redis:7-alpine volumes: - redis_data:/data healthcheck: test: [CMD, redis-cli, ping] interval: 10s timeout: 5s retries: 10 volumes: superset_home: pg_data: redis_data:几个参数值得展开说。8088 是 Superset 默认端口冒号左边改为主机端口右边不要动SUPERSET_CONFIG_PATH指向挂载进来的配置文件后续 worker、beat 进程都会读同一个配置depends_on配合condition: service_healthy是 compose 的新语法确保 postgres 和 redis 先通过健康检查再拉起 superset直接消掉最常见的启动即 500。healthcheck 用 python 而不是 curl因为 apache/superset 镜像不一定带 curl但 python 一定在。三个命名卷让容器删了数据还在生产环境千万别手滑执行docker compose down -v。3.2 superset_config.pySECRET_KEY、元数据库 URI 和基础开关配置文件挂载到容器里Superset 启动时由SUPERSET_CONFIG_PATH指定加载。下面是精简版的初始配置import os SECRET_KEY os.environ.get(SUPERSET_SECRET_KEY, change-me-in-production) TZ os.environ.get(TZ, Asia/Shanghai) # 元数据库用 postgres连接串里的 postgres 是 compose 服务名 SQLALCHEMY_DATABASE_URI os.environ.get( SUPERSET_DATABASE_URI, postgresqlpsycopg2://superset:supersetpostgres:5432/superset, ) # 缓存打到 Redis登录态和数据集缓存都不压本机 CACHE_CONFIG { CACHE_TYPE: RedisCache, CACHE_REDIS_URL: redis://redis:6379/0, } DATA_CACHE_CONFIG dict(CACHE_CONFIG) # 语言只保留中英文并把中文设为默认 LANGUAGES { en: {flag: us, name: English}, zh: {flag: cn, name: 中文}, } BABEL_DEFAULT_LOCALE zhSECRET_KEY不固定的后果是容器每次重启session 签名密钥都变用户看着就像「登录态老丢」所以必须固定。连接串里的postgres用的是 compose 服务名不是 localhost——在容器网络里localhost 指向容器自己指向不了数据库。CACHE_CONFIG把缓存统一交给 Redis多 worker 下数据才互通如果 Redis 暂时没就绪先用默认内存缓存也能跑但不要带着这个配置上线。LANGUAGES 收窄语言列表避免 UI 上出现一长串没人用的语言选项配合BABEL_DEFAULT_LOCALE zh让新用户默认就是中文界面。3.3 初始化三步db upgrade、init、fab create-adminSuperset 首次启动前必须做三件事建元数据库表、初始化角色权限、创建管理员账号。用docker compose run而不是exec是因为这些命令要在 superset 的容器环境里执行而且初始化过程不希望被主服务的重启策略打扰# 先只起依赖确认 postgres 和 redis 健康 docker compose up -d postgres redis docker compose ps # 1. 在元数据库里建表 docker compose run --rm superset db upgrade # 2. 初始化角色、权限和默认配置 docker compose run --rm superset init # 3. 创建管理员账号 docker compose run --rm superset fab create-admin \ --username admin \ --firstname admin \ --lastname user \ --email adminexample.com \ --password admin123456 \ --app superset # 4. 正式拉起主服务 docker compose up -d docker compose psdocker compose run --rm superset ...会临时起一个新容器执行命令--rm用完即删它继承 compose 中定义的环境变量、挂载和网络但不会动你已经 up 的 superset 容器。db upgrade是数据库迁移等价于旧版的superset upgradeinit灌入 Superset 必需的角色、权限和默认指标fab create-admin是 Flask-AppBuilder 创建管理员的命令--app superset不能漏它告诉命令行该用哪个 Flask 应用对象。三步顺序必须固定先 init 再 create-admin 会在角色缺失时报错。注意离线环境不要执行superset load_examples它会去公网拉示例数据集断网必然失败。示例数据不影响功能验证直接跳过。3.4 启动顺序与日志观察常见错误是图省事直接docker compose up -d然后看 superset 容器反复重启。原因多半是 postgres 还没就绪或者 db upgrade 没跑。正确的启动顺序是依赖容器 → 初始化命令 → 主服务。主服务起来后用docker compose logs -f superset看日志看到Running on http://0.0.0.0:8088说明 gunicorn 已经起来如果停在Initializing...或者反复打 traceback基本可以断定是配置或依赖问题优先查元数据库连接串和 SECRET_KEY。4. 中文版落地的关键动作语言开关、时区设置与翻译补漏标题里的「中文版」不是找一个汉化包装上就完事而是三条线同时落地界面语言默认中文、时区和日期格式贴合本地习惯、官方翻译覆盖不到的地方有补漏路径。很多人在线部署时可以靠浏览器翻译插件撑过去离线交付到客户手里这一套就必须做扎实。4.1 两种打开中文界面的方式Superset 有内建的 i18n 机制语言包已经编译在官方前端资源里不需要重新构建就能切到简体中文。第一种方式是登录页右下角的语言下拉框或者登录后点右上角用户头像在菜单里找语言选项但如果 superset_config.py 里的LANGUAGES没把 zh 列进去这个选项根本不会出现。第二种方式是在配置里直接设默认语言就是我前面写的BABEL_DEFAULT_LOCALE zh它让所有新用户打开的默认界面就是中文不需要每个用户手动去切。改完配置记得执行docker compose restart superset重启后前端会重新加载配置。有一点要提醒已经登录过的用户浏览器本地可能会记住之前选的语言如果升级前用户切过英文升级后还要去个人设置里改回来。交付验收时最好用一个全新浏览器窗口去测那才能代表真实用户的第一视角。4.2 时区、LANG 与日期格式的配套修改中文环境往往伴随一个诉求时间别显示成 UTC。compose 里我已经写了TZ: Asia/Shanghai它影响容器内进程的本地时间计算但 Superset 界面里「默认时区」是每个用户在个人设置里单独控制的两者是两回事。服务端 TZ 管的是日志时间戳、定时任务触发点界面展示的时间还要在用户设置里选「Asia/Shanghai」或者系统默认时区。LANGzh_CN.UTF-8这类系统级 locale 对 Superset 的界面翻译不起直接作用因为它的翻译走的是 Flask-Babel 的语言包不依赖操作系统 locale但保留这个环境变量没有副作用能避免容器内一些命令行工具输出乱码。日期格式则跟着浏览器 locale 走浏览器是中文环境SQL Lab 里的结果表时间格式就会按中文习惯渲染。这四项配置凑齐使用体验才接近「中文版」。| 配置项 | 位置 | 作用 | 建议值 | | LANGUAGES | superset_config.py | 控制可选语言列表 | 只留 en 和 zh | | BABEL_DEFAULT_LOCALE | superset_config.py | 新用户默认界面语言 | zh | | TZ | compose environment | 容器时区 | Asia/Shanghai | | LANG | compose environment | 系统 locale | zh_CN.UTF-8 |4.3 官方翻译不够用重建语言包的成本与替代路径上线一周后最常听到的反馈是「菜单是中文了图表配置面板怎么还有英文」。这是官方翻译覆盖率决定的zh 语言包覆盖了主框架但比较偏的属性文案、插件类图表的配置项仍有大量词条回退到英文。处理办法有三条第一条等版本更新Apche Superset 每个小版本都会补翻译词条4.1 到 4.2 的翻译差异往往能解决一半问题。第二条接受现状把翻译核对放进验收测试阶段先明确哪几个页面必须全中文不把颗粒度标准无限放大。第三条自己重建前端语言包这需要联网机上把 4.1.1 源码拉下来改superset-frontend/src/locales/zh.ts补充词条再npm ci npm run build编译静态资源最后覆盖进镜像。这条路成本很高npm ci 一次要拉几百 MB 依赖内网还得先把 node_modules 缓存搬进来除非甲方把翻译颗粒度写进验收条款否则不建议上线前临时搞。我一般走第二条先交付官方中文把翻译核对清单交给测试同事圈出他们真正在用的功能页面再决定要不要为那几个页面定向补翻译。血泪经验是不要为了某个冷门图表类型的一句英文标题去搭一整条前端构建流水线投入产出比太低。4.4 离线环境千万别碰 load_examples官方文档和大量博客都会让你注册示例数据命令就是superset load_examples。这个命令会从 GitHub 的 raw 地址拉取 CSV 和 JSON离线环境下只会看到超时或者连接错误而且它失败后会把db upgrade建好的表空间弄得很乱看起来像初始化坏了。正确的做法是准备好自己的测试数据比如在内网数据库里建两张业务表然后走「连接数据源 → 添加数据集 → 创建图表 → 保存仪表板」这条完整链路去验证中文文案和基础功能。这一条对标题里的「离线」二字是最直接的回应凡是需要外网的命令都要提前绕开。5. Superset 离线部署避坑从镜像导入到数据库驱动的五个踩坑记录这章记录的是我实际交付时翻过车、也被客户现场陪着走过的五个高频问题。每条都按「现象 → 原因 → 解决」写配置和命令可以直接抄。5.1 镜像导入后 tag 丢失与 docker 权限不足现象内网机上docker load执行成功但docker images里只有一堆none启动 compose 时提示image not found另一台机器上直接报permission denied while trying to connect to the docker daemon。原因tag 丢失几乎都是 save 时用镜像 ID 导出导致的镜像 ID 不带仓库名和标签load 后自然没有可读的 REPOSITORY。权限问题则是当前用户不在 docker 组里或者 docker 守护进程没起来和离线环境本身无关。解决导出一律写仓库名:标签比如apache/superset:4.1.1load 后先用docker inspect apache/superset:4.1.1 | grep RepoTags核对再继续下一步。权限问题给当前用户加 docker 组后重新登录即可命令是sudo usermod -aG docker $USER如果 docker 服务本身挂了先systemctl start docker。5.2 元数据库连不上服务名和健康检查顺序现象superset 启动后一直 500日志里出现could not translate host name postgres或者connection refused有时 db upgrade 怎么跑都提示连不上数据库。原因连接串里把地址写成了localhost。在 compose 网络里localhost 指向容器自己不是 postgres 容器另一个隐藏原因是 postgres 还没完成初始化superset 就抢着去连一次两次可以重试反复重试就会被容器健康检查判定为失败。解决SQLALCHEMY_DATABASE_URI里写postgres:5432用服务名做主机名compose 里依赖服务加上condition: service_healthy让 db 先被pg_isready确认。排查时可以用docker compose exec superset python -c import socket; print(socket.gethostbyname(postgres))验证容器间 DNS 解析是否正常。5.3 登录态反复失效SECRET_KEY 没有固定现象每次容器重启后所有用户都要重新登录或者同一台机器刷新两次页面就掉线。原因SECRET_KEY没配置或者每次启动由随机逻辑生成。Superset 用它给 session cookie 做签名密钥一变旧 cookie 全部失效。解决在 superset_config.py 里固定SECRET_KEY生产环境用随机长字符串不要用change-me这种默认值。多节点部署时所有节点要配置同一个 SECRET_KEY否则负载均衡切到另一台节点时照样掉登录态。改完配置记得docker compose restart superset同时把浏览器里的旧 cookie 清一次避免测试时误判。5.4 数据源测试连接报缺驱动装错层次的经典现场现象在 Superset 里添加 MySQL 数据源测试连接弹窗直接报ModuleNotFoundError: No module named pymysql查宿主机 Python 环境依赖明明已经装过了。原因Superset 跑在容器里它用的 Python 环境是镜像自带的宿主机上的任何 pip 包装了也看不到。还有一个变体是装进了容器但容器重启后镜像没有变更装进去的包又丢了。解决按第 2 章的方式构建superset-local:4.1.1扩展镜像把驱动打进镜像层连接串的方言也要匹配驱动MySQL 是mysqlpymysql://PostgreSQL 是postgresqlpsycopg2://。如果发现驱动确实在镜像里但还报错进容器手动python -c import pymysql验证大概率是连接串写错驱动名。5.5 初始化命令报错顺序问题与日志定位现象superset init中途报错或者fab create-admin说找不到角色还有一种是db upgrade执行到一半卡住表结构只建了一半。原因绝大多数是顺序不对db upgrade没跑成功就执行init角色表都不存在卡住多半是 postgres 容器没有健康检查数据库还在恢复流程中master 进程独占表锁。解决严格按 db upgrade → init → create-admin 的顺序执行postgres 的 healthcheck 里用pg_isready确认 READY 后再初始化。定位失败原因时看docker compose logs superset | grep -E ERROR|Traceback如果信息不够把SUPERSET_LOG_LEVEL临时调到 DEBUG复现一次后改回 INFO。排查顺序我固定为健康检查 → 容器日志 → 配置文件语法 → 数据库连接串按这个顺序走九成问题能在前两步找到答案。6. 部署完怎么验证与备份健康检查、元数据库转储和下次升级的后悔药部署完成不等于交付完成我每次都会先跑一遍最小验证链路再把备份机制留给客户。Superset 暴露了/health端点容器健康检查用的就是它手动验证可以直接curl -s http://127.0.0.1:8088/health # 返回 OK 说明 Web 服务正常功能验证不要只看登录页。我习惯走这条链路用 admin 账号登录 → 添加一个 MySQL 数据源 → 新建数据集 → 拖一个图表 → 保存到仪表板。这五个动作跑完说明 Web 服务、元数据库、缓存、数据源驱动、中文界面全链路都工作了。中间任何一步报错都值得回到第 5 章对应的坑里去对照。备份是私有化交付里最容易欠的账。Superset 的资产几乎都存在元数据库里所以备份的核心是 pg_dump再加上配置文件和镜像存档三样各留一份就够# 元数据库转储按日期命名 docker compose exec postgres pg_dump -U superset superset -F c -f /backup/superset_$(date %Y%m%d).dump # 配置文件和 compose 文件单独打包 tar czf superset_conf_$(date %Y%m%d).tar.gz docker-compose.yml superset_config.py升级这件事我吃过亏。第一次给客户升级时没留备份db upgrade跑到一半失败仪表板图表丢了一部分现场顶着压力回滚。后来我养成一个习惯任何版本变更前先做一次 pg_dump再 docker save 旧镜像存档两个都确认无误才开始动。万一升级失败pg_restore把元数据找回来旧镜像重新 load 也能就地回到原版本这是离线部署里最实用的后悔药。离线部署和在线部署的差别其实不在命令本身而在每一步都要问一句「断网之后这个操作还能不能成」。镜像能 save 出来驱动能打进镜像初始化能一条条跑通中文界面能默认展示这四件事做扎实Superset 4.1.1 的离线交付就没有黑匣子。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑