Docker Compose部署Metabase:应用库隔离与日期筛选看板

MB_DB_HOST=localhost会把数据库连接指向Metabase容器自身;把业务只读账号填进MB_DB_USER,又可能卡在应用表初始化。页面能打开后,还可能遇到日期控件只影响一张图。这些问题属于不同配置层。本文用固定版本Compose把应用库身份、数据源身份和逐卡片筛选分开,附角色查询与现象排查表。

本文按官方部署、权限和筛选资料整理,仅完成静态检查,没有执行镜像拉取、容器启动或样例查询。下面的命令由读者在自己的演示环境运行,文中不预设启动耗时、样例总数或查询结果。

1. 环境与两类数据库边界

环境为Linux、Docker Engine 28及以上、Compose v2及OpenSSL;固定镜像为Metabase v0.64.2和PostgreSQL 18.6-bookworm。使用新目录与新空数据卷,不用于覆盖已有H2实例。

连接 配置入口 用途与权限
应用库metabaseapp 启动环境变量MB_DB_* 保存用户、问题、看板;需要创建和修改应用表
分析数据源 Metabase管理界面 本文是内置Sample;真实业务库优先独立只读账号

官方建议正式环境使用PostgreSQL作为应用库。默认H2应用库适合演示;Sample Database也是H2,但承担的是演示数据源职责。应用库已经切到PostgreSQL,仍看到Sample使用H2是正常现象。

2. 配置密码、初始化脚本和Compose

进入专门的新目录,先生成.env。生成的是十六进制随机值,避免特殊字符被环境变量插值误读。配置文件和密码不要提交到公开仓库。

bash 复制代码
umask 077
printf 'PG_ADMIN_PASSWORD=%s\nMB_DB_PASSWORD=%s\n' "$(openssl rand -hex 24)" "$(openssl rand -hex 24)" > .env

保存init-metabase.sh,由PostgreSQL初始化时创建普通登录角色和它拥有的应用库:

bash 复制代码
#!/usr/bin/env bash
set -eu
psql -v ON_ERROR_STOP=1 -U postgres -d postgres --set=app_pass="$MB_DB_PASSWORD" <<'SQL'
CREATE ROLE metabase LOGIN PASSWORD :'app_pass';
CREATE DATABASE metabaseapp OWNER metabase;
SQL

保存后执行chmod 755 init-metabase.sh。脚本不含密码字面值,可以供容器内的PostgreSQL系统用户读取和执行;.env继续保持仅当前用户可读。这样也避免前面的umask 077让脚本变成容器内不可读的文件。

同目录保存compose.yaml:

yaml 复制代码
name: metabase-demo
services:
  appdb:
    image: docker.1ms.run/library/postgres:18.6-bookworm
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: ${PG_ADMIN_PASSWORD:?set password}
      MB_DB_PASSWORD: ${MB_DB_PASSWORD:?set password}
    volumes:
      - appdb_data:/var/lib/postgresql
      - ./init-metabase.sh:/docker-entrypoint-initdb.d/10-metabase.sh:ro
    healthcheck:
      test: ["CMD", "pg_isready", "-h", "127.0.0.1", "-U", "postgres", "-d", "postgres"]
      interval: 10s
      timeout: 5s
      retries: 12
  metabase:
    image: docker.1ms.run/metabase/metabase:v0.64.2
    restart: unless-stopped
    ports:
      - "127.0.0.1:3000:3000"
    environment:
      MB_DB_TYPE: postgres
      MB_DB_HOST: appdb
      MB_DB_PORT: 5432
      MB_DB_DBNAME: metabaseapp
      MB_DB_USER: metabase
      MB_DB_PASS: ${MB_DB_PASSWORD:?set password}
      JAVA_TIMEZONE: Asia/Shanghai
    depends_on:
      appdb:
        condition: service_healthy
volumes:
  appdb_data:

这里没有把POSTGRES_USER改成应用账号,因为官方镜像用该变量创建的是超级用户;初始化脚本创建的metabase才是供应用连接的普通角色。它拥有专用应用库,可以执行Metabase的表初始化与迁移,不承担业务库查询身份。

PostgreSQL 18的卷目标为/var/lib/postgresql,默认数据目录位于版本子目录。固定tag有助于控制升级窗口,但tag不是内容不可变保证;需要严格制品一致性时,应另核对应架构及镜像摘要。

初始化脚本只在空数据目录运行。若已有卷,改.env不会修改库内密码,补脚本也不会自动创建角色;先确认数据状态,再使用数据库管理流程调整,不能直接删除卷。

3. 启动与连接检查

bash 复制代码
docker compose config --quiet
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=100 appdb metabase

两项镜像均使用毫秒镜像的完整地址;镜像拉取和服务初始化分开定位。若pull失败,先检查镜像路径、固定tag、认证及网络;不要同时改数据库密码或看板参数。

应用库健康检查走TCP,避免把初始化阶段只监听本地socket的临时数据库当作最终服务。service_healthy负责启动门槛,不证明Metabase已完成自身迁移;继续检查应用日志和页面。

如果初始化脚本曾失败,容器重启后也不一定再次执行。应保留日志,先查角色和数据库是否已创建;根据失败位置修复现有状态。本文不提供删除卷的清理捷径,因为同一个命令在已有业务内容的实例上会带来完全不同的后果。

本机打开http://127.0.0.1:3000。若部署在远程机器,在本机执行ssh -L 3000:127.0.0.1:3000 用户名@服务器地址,通过隧道访问。此配置没有开放数据库端口,也没有把Web服务直接暴露到公网。

可用下面的查询核对应用角色。预期rolsuper为f,数据库为metabaseapp;这些是验收目标,不是本文实测输出。

bash 复制代码
docker compose exec -T appdb psql -U metabase -d metabaseapp -c "SELECT current_database(), current_user, rolsuper FROM pg_roles WHERE rolname = current_user;"

4. 创建订单卡片并接入日期筛选

首次设置创建管理员账号,数据源步骤选I'll add my data later。从Sample Database打开Orders。若样例被删除,管理员可到Admin → Databases选择Bring the Sample Database back。

先按Created At升序和降序查看边界,记录实际样例日期范围。不要假设数据包含今天;使用"最近30天"得到空结果,可能只是选到了样例范围之外。

新建问题,数据选Orders,汇总选Count,用数字图保存为"订单总数"。再次从Orders新建问题,同样使用Count,按Created At的"月"粒度分组,用折线图保存为"每月订单数"。两题均不预加日期条件,也不使用SQL变量,减少筛选映射的额外复杂度。

新建看板并加入这两题。进入编辑模式,添加看板级Date picker → Date Range,命名"订单日期"。在每张卡片的映射下拉框中分别选择Orders → Created At,保存看板。

筛选器的存在与字段连接是两步。若没有连接当前页的任何卡片,控件可能不会显示;只连接一张卡片,另一张图不会自动获得同样的筛选责任。

日期范围控件与按月分组也不是同一设置:前者决定哪些原始订单参与计算,后者决定结果怎样分桶展示。若只想看某个月,应选择覆盖该月的日期区间;不要为了让图"像月报"而把筛选错误地接到订单编号或其它非日期字段。

验收选择样例范围内两个不同区间,确认两卡同时重算;同一区间各月计数之和应等于总数卡。清除筛选,确认回到全量;重新打开看板,确认映射和标题仍保留。这里的Count统计订单记录数,不能当作商品件数或收入。

5. 按现象查错,避免混改两条连接

现象 优先核对
Metabase持续重启 appdb日志、角色/库是否存在、MB_DB_HOST是否为服务名appdb
密码错误但.env已改 卷是否旧库;初始化变量不会给已有账号改密
创建或迁移表报权限错误 是否错误地把只读业务账号填到MB_DB_USER
图表显示空结果 先清日期条件,再核样例范围与问题自身的过滤条件
一张图变化、一张不变 分别检查两卡到Created At的映射并保存

容器内的localhost指向当前容器,不能拿它代替另一服务的主机名。应用库备份也不是业务库备份;本例的命名卷只是持久化位置,仍应另做备份并验证恢复。

6. 接入真实业务库前的交接

在管理界面新增业务数据源,配置独立只读账号,并只授权需要分析的表或视图。应用库账号与业务查询账号分开;数据库权限和Metabase组权限也应分别检查。需要上传、动作等写入功能时,应单独评估写连接,不直接扩大普通分析账号的权限。

升级前可导出应用库,备份文件应存到独立位置,并配合部署配置、密码保管及恢复演练:

bash 复制代码
umask 077
docker compose exec -T appdb pg_dump -U metabase -d metabaseapp -Fc > metabaseapp.dump

已有H2应用库要保留旧问题时,需按迁移流程处理;只改环境变量会指向另一个库,不会自动搬迁旧内容。本例是单机入门配置,未覆盖HTTPS、团队权限、高可用、容量评估与恢复演练。处理同类故障时,记录三项证据:应用连接查到的库名与角色、初始化失败的具体日志、两张卡片各自映射的日期字段。用证据确定故障层,再修改该层配置,避免一次更换镜像、密码和筛选条件后无法判断原因。

相关推荐
闲云自留地43 分钟前
Kubernetes 安装保姆级:关 swap、装 containerd、init 集群、calico 一篇通
容器·贪心算法·kubernetes
讯捷蓝达1 小时前
台山曙光I620-G20服务器RAID5离线数据恢复全过程
运维·服务器
怒放的生命19911 小时前
前端项目 Docker 打包实操指南
前端·docker·容器
tedcloud1231 小时前
Docker Compose 部署 Immich:手机照片自动备份与常见故障排查
运维·前端·docker·容器·智能手机·开源·流程图
古城小栈1 小时前
Docker Compose 云原生的底座
docker·云原生·容器
Android系统攻城狮1 小时前
Linux Gstreamer深度解析之gst_audio_ring_buffer_activate调用流程与实战(七十九)
linux·运维·服务器·gstreamer音视频·gstreamer音视频进阶
小羊没烦恼!1 小时前
在.net中读写config文件的各种方法
java·大数据·运维·服务器·前端·数据库·oracle
卜锦元2 小时前
Docker Compose 部署 Nginx 1.30.6 完整指南
nginx·docker·容器
Escalating_xu2 小时前
【Linux 网络编程】网络命令加餐:用 ping、netstat、watch 和 pidof 排查服务问题
linux·运维·网络