首页 / 资讯中心 / 文章详情

Superset 4.1.1 Docker离线部署中文版实战:内网BI平台搭建与避坑指南

Superset 4.1.1 Docker离线部署中文版实战:内网BI平台搭建与避坑指南 ★ FEATURED ARTICLE
简介这是一份面向需要内网或离线环境部署数据可视化平台的企业开发者与运维人员的中文版 Superset 4.1.1 Docker 离线部署包。通过容器化方式打包了 Superset 及其依赖解决了无外网条件下安装配置复杂、中文支持不足的痛点适用于数据分析团队快速搭建 BI 看板。压缩包共 6 个文件约 524.2MB包含 3 个 Docker 镜像 tar 包Superset 中文镜像、PostgreSQL 14、Redis 7以及 docker-compose.yml 服务编排文件、superset_config.py 配置文件与 .env 环境变量文件覆盖了从镜像加载到容器启动的完整离线部署要素。已有 367 人学习下载。用户拿到后可直接导入本地 Docker 环境按编排文件启动服务免去手动拉取镜像和逐项配置的繁琐流程配套的配置示例与环境变量模板也可作为后续调优和二次开发的基础适合希望快速获得开箱即用中文可视化环境的中高级使用者。1. Superset 4.1.1 中文版 Docker 离线部署给隔离内网装上一套能用的 BI 平台把 Superset 4.1.1 装进一台完全断网的机器还要让图表标题、下拉选项、按钮提示能显示中文这活儿比大多数人想象的麻烦。去年某单位的数据分析平台选了它运维把 Docker 镜像传进去、容器一启动图表倒是能出但界面英文、报表导出全方块字折腾两天才全部理顺。问题非常多而且每一步的坑都不在官方文档里。这篇笔记写给两类读者一类是给政府、金融、能源等内网环境做数据平台的人另一类是本地开发环境特殊、只能手动搬运镜像的开发者。目标是让你拿到一套能复现的操作路径从镜像准备到最后中文界面的落地全部在离线状态完成。我会按我实际部署的顺序来讲该给参数的地方给参数该给命令的地方给命令后面还附上我踩过的几个真实问题。Superset 是个开源 BI 工具负责把数据库里的数据变成可视化图表和仪表盘。离线部署这事卡在三个环节Docker 镜像怎么搬进内网、容器配置和初始化怎么做、中文资源怎么补全。下面我们一个个拆开。2. 离线镜像准备先想清楚要带哪些东西再动手2.1 拖镜像之前先把依赖拓扑理清楚很多人以为离线部署就是把apache/superset:4.1.1这个镜像docker save出来拷进去docker load就收工。实际用起来就会发现Superset 的镜像只是运行框架元数据库、数据源连接器、初始化脚本这些都得自己配。你至少要搞清楚三件事你计划用哪个数据库存 Superset 自身的配置和看板元数据、要连哪些业务库、需不需要额外的 Python 依赖。我一般这样选元数据库用 PostgreSQL 或 MySQL单独起一个容器业务数据源看情况可能是另一个 MySQL 也可能是 Oracle。这样的话除了 Superset 镜像本身还得准备对应数据库的 Docker 镜像。如果你把元数据存在 SQLite 里那确实只要一个 Superset 镜像就够了但生产环境我不这么干后面会在避坑章解释原因。选定了容器方案接下来就是离线搬运的核心路径。在有网的机器上把镜像docker pull下来然后docker save成 tar 包拷贝到离线机器上docker load。注意docker save和docker export是两码事前者把镜像的完整分层结构保留后者只导出容器的文件系统快照。离线部署必须用save/load否则迁移过去镜像的标签和构建历史会丢后续写 docker-compose 时容易对不上。2.2 有网环境下的镜像准备清单先在有网的机器上把下面这些镜像拉下来# 在有网环境的机器上执行 docker pull apache/superset:4.1.1 docker pull postgres:16-alpine docker pull redis:7-alpine为什么要 RedisSuperset 的异步查询和缓存都需要一个消息队列默认用的是 Celery 加 Redis 的组合。很多第一次做离线部署的人会跳过这一步结果图表刷新一多数据库直连查询就卡死。单机部署时 Redis 是 Superset 的默认配置里指定要用的我一般建议带上。镜像拉好之后逐个保存成 tar 文件。如果你内网机器磁盘比较紧张这份清单里有镜像压缩体积的参考但具体以实际产物为准# 创建存放镜像的目录 mkdir -p ./offline-images docker save -o ./offline-images/superset-4.1.1.tar apache/superset:4.1.1 docker save -o ./offline-images/postgres-16.tar postgres:16-alpine docker save -o ./offline-images/redis-7.tar redis:7-alpine这三条命令没有技术难度但有一个参数细节值得注意docker save默认导出的是镜像的全部历史层文件比较大。如果你确认内网机器不需要回滚到镜像的某个历史版本可以用--quiet参数但实际减少不了体积要减小体积就用docker save导出后gzip压缩或者从 registry 上直接拉压缩格式。我习惯导出后顺手gzip这个操作对内网拷贝速度的影响非常明显。2.3 离线环境导入镜像的验证tar 包到了内网机器之后导入并验证完整性# 在离线机器上执行逐个导入 docker load -i ./offline-images/superset-4.1.1.tar docker load -i ./offline-images/postgres-16.tar docker load -i ./offline-images/redis-7.tar # 确认镜像列表 docker images | grep -E superset|postgres|redis导入后看到REPOSITORY和TAG列正确显示apache/superset、4.1.1字样才能继续。如果TAG显示成none那基本可以断定前面用过docker export而不是docker save或者镜像来源不规范重新用docker save处理一遍即可。这里有一个常见坑需要提前预警内网机器的 Docker 版本如果比生成镜像的机器旧load时偶尔会报不支持的特性错误。遇到这种情况先检查两边的 Docker 版本我遇到过 20.x 和 24.x 之间不兼容的情况比较省事的做法是内网机器也升级到接近的 Docker 版本。别在这上面带着旧版本死磕否则会消耗大量时间。3. 离线环境下的 Docker Compose 编排与初始化3.1 最小可用的 docker-compose.yml镜像准备到位后接下来是编排。Superset 4.1.1 版本对容器化部署的支持集中在 docker-compose 方式上。我用一个最小可跑的组合包含三个服务Superset 本体、PostgreSQL元数据库、Redis缓存和异步任务队列。version: 3.8 services: postgres: image: postgres:16-alpine environment: POSTGRES_USER: superset POSTGRES_PASSWORD: superset-pass POSTGRES_DB: superset volumes: - pg-data:/var/lib/postgresql/data restart: always healthcheck: test: [CMD-SHELL, pg_isready -U superset] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine volumes: - redis-data:/data restart: always superset: image: apache/superset:4.1.1 container_name: superset-app environment: SUPERSET_CONFIG_PATH: /app/pythonpath/superset_config.py SUPERSET_SECRET_KEY: your-random-secret-change-me SUPERSET__CACHE_CONFIG: {RedisCache: {host: redis, port: 6379, db: 0, timeout: 300}} volumes: - ./superset_config.py:/app/pythonpath/superset_config.py - superset-home:/app/superset_home ports: - 8088:8088 depends_on: postgres: condition: service_healthy redis: condition: service_started restart: always volumes: pg-data: redis-data: superset-home:参数说明SUPERSET_CONFIG_PATH必须指向/app/pythonpath/superset_config.py容器启动时会加载这个文件SUPERSET_SECRET_KEY是你实例的会话签名密钥不设置的话每次重启所有用户的登录态都会失效写死一个随机字符串即可SUPERSET__CACHE_CONFIG那一串写法是 Flask 的配置穿透语法双下划线会把值注入到嵌套结构里目的是让 Superset 用 Redis 做缓存而不是默认的内存缓存。3.2 初始化元数据库与管理员账号这里要格外注意容器内命令的执行环境。Superset 的官方镜像默认用 root 用户启动吗实际上 4.x 镜像里有一个superset用户但配置目录的权限需要处理好。先启动依赖服务再跑初始化# 启动 PostgreSQL 和 Redis docker compose up -d postgres redis # 等待 PostgreSQL 健康检查通过然后初始化元数据库 docker compose run --rm superset db upgrade # 创建管理员账号交互式输入用户名、密码等 docker compose run --rm superset fab create-admin # 完成 Superset 初始化创建默认角色和权限 docker compose run --rm superset initdocker compose run --rm superset和docker compose exec superset的区别在于前者会新起一个临时容器执行命令适合初始化这种一次性操作后者要求容器已经处于运行状态。跑db upgrade时如果配置里的数据库连接串写错了执行过程会卡很久然后报连接错误所以先确认superset_config.py里的SQLALCHEMY_DATABASE_URI指向的是 PostgreSQL 地址而不是默认的 sqlite 路径。初始化完成后把整个服务组拉起来docker compose up -d # 查看日志确认没有报错 docker compose logs -f superset正常启动的日志尾部会出现HTTP Server on http://0.0.0.0:8088/之类的输出端口号和实际配置对应。之后浏览器访问http://内网机器IP:8088应该能看到登录页了用上一步创建的账号就能登进去。但这只是英文版接下来要处理的就是标题里说的中文版。4. 中文版落地语言包、字体与本地化配置4.1 先打开 Superset 自带的国际化开关Superset 4.x 本身带了一部分中文本地化翻译文件只是默认没有启用。你需要做两件事设置语言环境变量然后在用户偏好里把语言改成中文。# docker-compose.yml 的 superset 服务环境变量里追加 environment: LANG: zh_CN.UTF-8 LC_ALL: zh_CN.UTF-8修改完docker compose up -d重启服务然后登录界面右上角头像里的 Profile 设置里找 Language 选项切换为中文简体。但这个时候你会发现界面大约七成是中文剩下的菜单项、图表组件属性还是英文。这是 Superset 官方翻译没有完全覆盖造成的很难通过配置彻底解决。标题里的“中文版”我一般理解为两层界面语言基本中文化以及图表导出和展示时中文文字能正常渲染。前者靠语言包切换后者才是真正的填坑环节。4.2 中文字体缺失是最容易翻车的隐藏问题镜像内部用的是精简 Linux 系统自带的字体通常不含中文。你会发现看板标题里的中文在网页上显示得出来因为浏览器用自己的字体渲染了但导出 PDF 或图片时中文变成一个个方块或乱码。这是因为服务端渲染图表时找不到中文字体就用了系统默认的字形。常见做法是把宿主机里的中文字体挂载进容器或者把字体文件拷进去更新字体缓存# 在宿主机准备一个字体目录放入中文字体文件如 Noto Sans CJK 或文泉驿正黑 mkdir -p ./fonts # docker-compose.yml 的 superset 服务中追加卷挂载 # - ./fonts:/usr/share/fonts/chinese:ro挂载完成后进入容器更新字体缓存docker compose exec superset bash # 在容器内执行 apt-get update apt-get install -y fontconfig fc-cache -f /usr/share/fonts/chinesefc-cache的作用是扫描字体目录并生成缓存文件命令没有输出一般就代表成功。验证方法是用 Python 在容器里跑一下看能不能识别到中文字体如果字体生效就能看到字形信息。4.3 数据库连接串与中文数据集连接的业务数据库如果是 MySQL连接串里要明确指定字符集。否则表里的中文字段名、维度值在 Superset 元数据库里存的时候可能变成乱码# superset_config.py 中 MySQL 连接串写法 SQLALCHEMY_DATABASE_URI mysqlpymysql://user:passwordmysql-host:3306/dbname?charsetutf8mb4charsetutf8mb4不是随便写的MySQL 默认用utf8mb4_general_ci排序规则连接层不声明字符集的话BI 工具从连接池读数据时很容易按 latin1 解析中文直接变问号。这一行配置能省掉后面非常多的排障。元数据库侧的 PostgreSQL 连接串也一样写但要注意编码要在建库时定好。对部署流程来说到这一步中文版才算是真正可用的。但这套链路很长拼装起来的小坑特别多我把高频问题整理在下一章新手照着对号入座能省很多事。5. 离线部署 Superset 的常见问题排查与避坑记录5.1 容器重启后配置和看板全部丢失这是一个高频事故。现象执行docker compose down之后再次up -d登录进去发现之前建的看板、数据源连接全都是空的等于回到了刚初始化的状态。原因Superset 的元数据如果没有持久化存储容器重建后数据就丢干净了。官方镜像默认把 SQLite 文件写到容器内的/app/superset_home而不挂载卷的话这个目录随容器销毁一起消失。你配置里用了 PostgreSQL 作为元数据库但 Superset 容器启动时如果环境变量没生效或配置文件里的SQLALCHEMY_DATABASE_URI还是 sqlite那等于白搭。解决查docker compose exec superset env | grep SUPERSET确认环境变量已传入再进容器看/app/pythonpath/superset_config.py里数据库连接串是不是真的指向 PostgreSQL。我在部署时遇到过 compose 文件里卷挂载路径写错的情况配置文件压根没被读进去容器用了镜像内置的默认配置。验一下docker compose exec superset cat /app/pythonpath/superset_config.py内容是自己写的才有用。5.2 登录页能打开但登录报 CSRF 错误现象输入账号密码点击登录直接跳到一个错误页提示 CSRF token 缺失或无效刷新偶尔能好。原因Superset 的密钥没有固定下来。容器每次启动生成一个随机的SECRET_KEY而浏览器里的会话是用旧密钥签名的新旧对不上就拒绝。这在离线部署第一次访问时特别容易遇到因为大家习惯先启动容器再慢慢配。解决提前在配置里固定SECRET_KEY。在superset_config.py里写一行SECRET_KEY a-hard-to-guess-random-string然后重启所有容器把浏览器 cookie 清掉重新登录。以后每次部署或迁移配置这个密钥都保持不变会话就不会因为重启而失效。5.3 图表查询很慢或一直转圈现象打开某个图表数据加载转圈几十秒甚至直接超时看板多个图表同时刷新时部分图表加载失败。原因默认配置里Superset 查询数据和缓存都走内存异步任务没有队列可用。而离线部署如果没带 Redis 镜像或者 compose 里 Redis 地址写错Celery 任务直接挂起。另一个常见原因是数据库连接池太小默认的DB_POOL_SIZE对并发查询不够用。解决一是确认 Redis 服务正常容器能 ping 通redis这个主机名二是在superset_config.py里调大连接池DB_POOL_SIZE 20 DB_POOL_RECYCLE 300这两行分别控制连接池大小和连接回收周期。按内网并发用户数来调20 不算大但足够支撑一个小团队的日常使用。如果看板里有大量图表继续往上加到 40。5.4 导出图片或 PDF 时中文变成方块现象看板导出成图片或 PDF 后所有中文全部变成方框英文和数字正常。原因容器里缺少中文字体文件。网页端显示中文是浏览器本地的字体渲染而导出操作是服务端调绘图库渲染服务端根本没有中文字体可用。这个问题在第 4 章已经写了解决方案这里强调排查顺序先确认字体文件确实挂载进去了再确认fc-cache刷新完成最后才怀疑是导出组件的 bug。用docker compose exec superset fc-list | grep -i cjk\|noto\|wqy查一下字体列表有输出说明字体已就位。5.5 镜像 load 成功但容器启动即退出现象docker compose up -d之后Superset 容器一直处于Restarting状态查日志发现报permission denied或某个模块初始化失败。原因第一类问题是挂载目录的权限不对。宿主机的./superset_config.py或./fonts目录对容器内运行用户不可读启动时加载配置或字体直接失败。第二类问题是文件格式不对比如在 Windows 下编辑的superset_config.py带 BOM 头Python 加载后第一行就报语法错。解决给配置和字体目录加chmod -R 755保证至少其他用户可读用dos2unix或直接在 Linux 里重新保存配置文件。如果是 Python 报语法错误看docker compose logs superset里的报错行号对着查。6. 部署完成后的验证技巧与我的收尾习惯部署完成、中文也正常了最后一步别急着收工我在每次离线部署完都会做一套固定的验证动作大概半小时内能跑完确保交付出去的不是个黑匣子。验证分三层。第一层是服务状态直接看所有容器是否健康运行docker compose ps健康状态的标准是Up且healthy如果有Restarting的容器说明基础环境还有问题先解决再继续。第二层是接口连通性Superset 暴露了一个健康检查接口不需要登录就能访问curl -s http://127.0.0.1:8088/api/v1/health/返回OK字符串则说明 Web 服务正常。如果这套部署是要交付给别人的我会把这两条命令连同curl的预期输出一起写进交接文档接手的人不用登录系统就能判断是否运行正常。第三层是业务侧的连通性验证新建一个数据库连接指向真实业务库创建一张最简单的表图表确认中文表和字段名能正常显示。这一步很关键很多部署在登录页看起来一切正常但连不上实际数据源因为没有在验收流程里把“用真实数据出图”这一环走下去。我见过有人只验证到登录页就交付结果业务方配好数据源后才发现连接串里的字符集配置是错的来回折腾。两次部署经验下来我的习惯是先把第 5 章里的问题清单打印出来放在手边遇到报错直接对着查解决方案比打开浏览器搜索高效得多。这套离线部署的链路不算复杂但每台内网机器的系统环境不一样Docker 版本、硬件架构、内网 DNS 都可能引入新问题。保持耐心按“镜像准备 → 编排启动 → 初始化配置 → 中文本地化 → 验证交付”的顺序一步步走基本上不会有大偏差。还有一个保存下来的实用脚本放在部署机上有备无患#!/bin/bash # check_superset_health.sh # 一键检查 Superset 部署状态的脚本 for port in 8088; do result$(curl -s --max-time 10 http://127.0.0.1:${port}/api/v1/health/) echo port ${port}: ${result} done for container in superset-app postgres redis; do status$(docker inspect -f {{.State.Health.Status}} ${container} 2/dev/null || echo not found) echo ${container}: ${status} done脚本里用了--max-time 10防止 curl 卡死docker inspect拉取的是容器健康状态字段注意检查superset-app这个名字和 compose 文件里的container_name一致。这个脚本本身没有技术深度但每次交付前跑一遍能快速暴露服务没有启动、健康检查挂了这类低级问题省去挨个容器排查的时间。另外最好在第一次启动完成后先把容器提交一份镜像快照方便彻底坏掉时能直接回滚这个操作某天会成为你的后悔药docker commit superset-app superset-backup:4.1.1-zh不过这只是保险措施日常更新配置还是改 compose 和配置文件重启别直接用commit代替版本管理。希望这些经验能帮到你省下几个加班的晚上。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站