OpenMetadata 1.5.6 Docker Compose安装排错 简介OpenMetadata 容器化部署手册面向开发者与运维人员聚焦这款开源一站式元数据管理平台在 CentOS 7 环境下的落地实践帮助读者搭建覆盖数据发现、数据血缘、数据质量与数据治理的服务实例。压缩包内仅含 1 个 doc 文件体积约 693KB内容按安装流程分章组织从系统环境与 Python3、JDK 依赖准备到 Docker 镜像源替换与 docker-ce 安装再到 docker-compose 部署、编排文件下载及 MySQL 密码、主机端口等参数修改最后给出服务启动与首页访问的验证方式结构清晰可对照逐步执行。手册还针对基础镜像拉取失败、版本差异等常见卡点给出替代思路与官方文档查阅建议便于在离线或网络受限场景中排查问题。已有 1354 人学习下载适合具备一定容器基础、希望低成本体验元数据管理平台的工程师参考。1. 版本先对齐OpenMetadata 1.5.6 的 docker 安装到底卡在哪先说我见过最典型的一次 openMetadata docker 安装翻车一台 CentOS 7 的机器docker 装好了docker-compose.yml 也拉下来了docker-compose up -d回车之后屏幕刷过去一百多行 Pulling最后停在浏览器打不开 8585docker ps一看容器全是 Up可 server 每隔两分钟重启一次。查了两个多小时才发现是三件事叠在一起MySQL 密码只改了一处、Elasticsearch 堆内存没往下调、基础镜像走的地址在目标网络里拉不动。这套环境不算复杂但它是 MySQL Elasticsearch 迁移容器 JVM 主服务 Airflow 采集端一起编排任何一个环节没对齐都会表现成「页面打不开」很有迷惑性。这篇按「装什么版本、怎么装、参数怎么改、坏了怎么救」走一遍环境固定为 CentOS 7 docker-ce 24 一线 python3 版 docker-compose 1.29.2 OpenMetadata 1.5.6 的官方 compose 文件。适合已经会用 docker、但第一次碰这套元数据平台组合的开发者新手照着能跑通熟手重点看第 4、5 章的参数取舍和排查记录。2. 环境底座CentOS 7 上装 docker-ce 24 与 python3.62.1 开工前先核资源这台机器扛不扛得住OpenMetadata 不是单个容器它至少要跑起 MySQL、Elasticsearch、主服务三个常驻容器迁移容器是一次性的采集端还带一套 Airflow。主服务和 Elasticsearch 都是 JVM内存是第一个要算清楚的账。4G 内存能起来但不留余量稍微点几下数据探查就可能触发 OOM8G 是跑得舒服的起点16G 以上再考虑开采集任务。磁盘同样容易低估。镜像本身占一部分Elasticsearch 的索引目录会随着元数据量和血缘关系增长50G 起步比较稳妥而且/var/lib/docker所在分区要留够别让根分区先满。资源项最低可跑建议配置说明CPU2 核4 核迁移和索引重建时吃 CPU内存4G8G 及以上ES 与主服务各占一个 JVM磁盘30G50G 及以上索引目录随血缘数据增长系统CentOS 7.6CentOS 7.9内核 3.10 及以上端口也要提前核对别等容器起来了才发现撞车。8585 是主服务 Web 端口3306 是 MySQL9200/9300 是 Elasticsearch 的 HTTP 与节点通信口采集端那条链路默认还会占 8080。上机第一件事# 看这几个端口有没有被别的服务先占了有输出说明冲突 ss -lntp | grep -E 8585|3306|9200|9300|8080ss -lntp里-l只看监听态-n不做域名解析-t限定 TCP-p带上进程名。有输出就逐个确认是不是非本机的业务占用了就得在 compose 里改宿主机侧端口或者先腾出来。2.2 装 docker-ce锁版本、换仓库、验证三项CentOS 7 上直接yum install -y docker-ce现在不一定好使仓库里最新几版对 CentOS 7 的支持在收缩容易报找不到包或者依赖不满足。我的习惯是锁 24 一线配合--nobest让 yum 在依赖冲突时退而求其次而不是直接失败。# 1. 基础依赖device-mapper 与 lvm2 是存储驱动的前置包 yum install -y yum-utils device-mapper-persistent-data lvm2 --skip-broken # 2. 加 docker-ce 仓库尖括号处换成你环境里能访问的镜像站域名 yum-config-manager --add-repo https://mirror-host/docker-ce/linux/centos/docker-ce.repo # 3. 仓库文件里默认写的是官方地址整体替换成镜像站否则后面装包还是会去外网 sed -i s/download.docker.com/mirror-host\/docker-ce/g /etc/yum.repos.d/docker-ce.repo # 4. 清掉旧缓存重建索引不然 yum 还在用老元数据 yum makecache fast # 5. 装指定版本三个包版本要一致 yum install -y docker-ce-24.0.9 docker-ce-cli-24.0.9 containerd.io --nobest # 6. 启动并设为开机自启少这一句重启机器后容器全没了 systemctl start docker systemctl enable docker--skip-broken的作用是跳过那些装不上的可选依赖不让整条命令回滚--nobest是告诉 yum 不要死磕最高版本允许它挑一个能装上的组合。第 3 步的sed不能省很多「装是装上了但拉镜像还是慢」的情况根子就在这里仓库地址换了包描述里的源地址没换。装完做两个层次的验证一个看客户端一个看服务端# 客户端版本能输出说明二进制在 docker -v # 服务端信息重点看这三行 docker info | grep -E Server Version|Storage Driver|Docker Root DirServer Version和客户端对得上说明 daemon 正常Storage Driver在 CentOS 7 上通常是 overlay2如果是 vfs 说明文件系统不支持性能会差一个量级Docker Root Dir默认/var/lib/docker磁盘紧张时在/etc/docker/daemon.json里改># 四个包一起装devel 是后面编译依赖时用的tools 里有调试工具 yum install -y python3 python3-devel python3-libs python3-tools # 补 pip 模块有些最小化安装的镜像是没有 pip 的 python3 -m ensurepip # 升级 pip但必须压在 22 以下3.6 装不了更新的版本 python3 -m pip install --upgrade pip22 # 装 wheel否则后面装 docker-compose 时可能报 bdist_wheel 缺失 python3 -m pip install wheel # 验证两条都要看 python3 -V python3 -m pip -V注意这里全程用python3 -m pip而不是直接敲pip。CentOS 7 上/usr/bin/pip很可能还指向 python2.7 的 pip用它装出来的包 python3 看不见症状是「明明装成功了执行 docker-compose 还是 command not found」。python3 -m pip -V的输出里会带上 pip 自己所在的路径一眼就能看出装到哪个解释器下面了。提示python3.6 已经停止维护作为 compose 的运行环境没问题但不要把公网可达的业务接口跑在它上面。2.4 防火墙与 SELinux先把 8585 放出来CentOS 7 默认开 firewalld容器做了端口映射宿主机防火墙不放行的话外面照样连不上。这一步很多人留到最后才想起来结果把排查方向带偏到容器网络上去。# 永久放行 8585加 --permanent 才是写进配置 firewall-cmd --add-port8585/tcp --permanent # 重载生效 firewall-cmd --reload # 确认端口在放行列表里 firewall-cmd --list-ports如果机器上 firewalld 没启用直接systemctl status firewalld看一眼别盲目执行。SELinux 方面卷挂载报Permission denied时先setenforce 0临时验证是不是它拦的确认后用semanage加规则而不是一直关着——这是我一直坚持的做法临时关可以长期关是给自己埋雷。3. 编排层准备docker-compose 1.29.2 与 1.5.6 版 compose 文件3.1 pip 装 docker-compose为什么锁 1.29.2docker-compose 从 2.x 开始换成 Go 重写并以 docker 插件形式分发python3.6 的 pip 根本装不上。1.29.2 是最后一个支持 py3.6 的版本所以在这里不是「保守」是唯一选择。# 锁版本安装不加版本号会去拿 2.x 然后编译失败 python3 -m pip install docker-compose1.29.2 # 验证输出里应该有 1.29.2 docker-compose -v # 顺手确认命令落在哪通常是 /usr/local/bin/docker-compose which docker-compose装完docker-compose -v报ImportError之类八成是 pip 版本过新或者 setuptools 太旧回退python3 -m pip install setuptools60再重装一次基本能解决。如果你的 docker 是 20.10 以上其实还有另一条路直接用 compose v2 插件二进制丢到/usr/libexec/docker/cli-plugins/docker-compose命令变成docker compose中间是空格。两者的差别要提前知道v2 会忽略 compose 文件顶部的version字段v1 则认它v1 的docker-compose down默认不删卷v2 的docker compose down -v才会连卷一起删。这篇主线走 v1因为 1.5.6 的官方文件是按 v1 的写法给的照抄最省事。3.2 建目录把 1.5.6 的 compose 文件拿下来文件别放家目录放/opt下权限清晰磁盘位置也好确认。目录建好之后第一件事是把原始文件备份一份改配置改崩了能立刻回滚。# 建工作目录并进入 mkdir -p /opt/openmetadata-docker cd /opt/openmetadata-docker # 下载 1.5.6 对应的 compose 文件 wget https://github.com/open-metadata/OpenMetadata/releases/download/1.5.6-release/docker-compose.yml # 确认文件下下来了大小不是 0 ls -lh docker-compose.yml # 备份原始文件改坏了直接 cp 回来 cp docker-compose.yml docker-compose.yml.bak命令里带1.5.6-release这一段版本号改一位拉到的就是另一套服务定义配置文件里的字段可能对不上。执行wget时报连接超时是常事那就用浏览器打开同一个地址手动下载再通过文件传输工具传到这台机器上落点还是/opt/openmetadata-docker。别在服务器上反复重试浪费时间。3.3 打开文件先认服务这几个容器分别干什么第一次看这个文件容易以为是单容器部署其实是一整套。先认清楚谁是谁后面排查日志才知道该看哪个。服务名作用默认端口是否常驻mysql元数据库存用户、表结构、配置3306是elasticsearch搜索与索引页面搜索、血缘图依赖它9200 / 9300是executeMigrations一次性执行数据库迁移脚本无否跑完退出openmetadata_server主服务Web UI 和 API 都在这8585是ingestion采集与数据探查内部带 Airflow8080视使用情况executeMigrations是最容易被误判的一个docker ps看不到它用docker ps -a才会看到一个 Exited (0) 的记录这是正常的、期望的结果。反过来如果它频繁重启或者退出码不是 0那主服务一定起不来因为表结构没建好。这一点在第 5 章还会展开。3.4 哪些字段该改哪些碰都别碰改配置最怕整段替换。这份文件里环境变量之间是有联动关系的改一处不改另一处症状往往隔了好几层才显现。我的划分是该改的MySQL 的 root 密码与业务账号密码、主服务和迁移容器里对应的数据库密码、端口映射的宿主机侧、镜像地址前缀、Elasticsearch 的堆内存参数。不该动任意值的服务名mysql、elasticsearch这些名字被写进了别处的连接串、DB_HOST这类指向服务名的变量、容器内部的端口号、depends_on顺序、DB_SCHEMA库名。服务名一改主服务就找不到数据库报的还是「连接被拒绝」很容易查偏。改之前拿diff记录自己的改动出问题时diff docker-compose.yml docker-compose.yml.bak一眼看出动过什么这比回忆改了哪里靠谱得多。4. 改配置docker-compose.yml 里 MySQL 密码、端口与镜像地址4.1 MySQL 密码三处必须同步改一处等于没改这是我在第 1 章提到的那次翻车的第一个原因。文件里数据库密码分散在至少三个位置它们的值必须完全一致否则主服务连库直接被拒。下面是我改完后的片段字段名以你下载到的 1.5.6 文件为准位置对应上就行。services: mysql: environment: MYSQL_ROOT_PASSWORD: ChangeMe_Root_2024 # root 密码只在容器内部用 MYSQL_USER: openmetadata_user # 业务账号别用 root MYSQL_PASSWORD: ChangeMe_OM_2024 # 业务账号密码第 1 处 MYSQL_DATABASE: openmetadata_db openmetadata_server: environment: DB_USER: openmetadata_user DB_USER_PASSWORD: ChangeMe_OM_2024 # 第 2 处必须和第 1 处一致 DB_HOST: mysql # 服务名别换成 IP DB_PORT: 3306 executeMigrations: environment: DB_USER_PASSWORD: ChangeMe_OM_2024 # 第 3 处迁移容器也要连库三处指的是MYSQL_PASSWORD、openmetadata_server的DB_USER_PASSWORD、executeMigrations的DB_USER_PASSWORD。只改第一处MySQL 容器会正常起来它只认自己的环境变量但主服务的日志里会出现Access denied for user openmetadata_user172.x.x.x然后不停重启。看到这个报错先回去比对这三行别急着怀疑网络。密码本身也有讲究。含$、#、:这类字符时要用双引号包起来YAML 里#后面是注释不引起来会被截断症状是「明明写了长密码登录却说不匹配」。密码里带$在 compose 里还可能被当成变量插值最稳的做法是只用字母数字加下划线和短横线。4.2 端口映射8585 要暴露3306 和 9200 只给本机端口映射的写法是「宿主机:容器」左边能改右边不能动。右边是容器内部的监听端口改了服务本身不知道直接连不上。openmetadata_server: ports: - 8585:8585 # 左侧宿主机端口可按需改右侧保持容器端口 mysql: ports: - 127.0.0.1:3306:3306 # 只绑回环外部访问不到 elasticsearch: ports: - 127.0.0.1:9200:9200 # 同理需要直连时用跳板机转发加127.0.0.1:前缀的意思是只监听本机回环网卡公网 IP 上不开放。这份文件原样跑起来MySQL 和 Elasticsearch 是对外裸奔的而在真实环境里元数据库里存着用户和权限信息Elasticsearch 里是全部元数据不该直接暴露。需要临时连库排查时在本机用客户端连127.0.0.1:3306或者用 SSH 端口转发别为了省事改成0.0.0.0。另外注意只写一个端口比如- 8585会让 Docker 随机分配宿主机端口docker ps里显示成0.0.0.0:32768-8585/tcp这种写法在只做内网访问时有用但排查时容易看花眼我不太用。4.3 镜像拉不动把镜像前缀换成自己能访问的仓库1.5.6 的 compose 文件里每个服务的image都指向公共镜像仓库。目标机器拉不动的时候docker-compose up会一直卡在 Pulling最后抛TLS handshake timeout或者manifest unknown。常见的做法是找一台能拉的机器先把镜像取下来打标签推到自己的私有仓库再改 compose 里的前缀。# 先把文件里所有 image 列出来一次性看清楚要处理多少个 grep -E ^\simage: docker-compose.yml | awk {print $2} | sort -ugrep抓 image 行awk {print $2}取第二个字段也就是镜像名sort -u去重排序输出就是一个完整的待处理清单。然后按清单逐个搬运以主服务为例# 在能访问公共仓库的机器上拉取tag 必须原样保留 docker pull openmetadata/server:1.5.6 # 重新打标签指向自己的仓库地址 docker tag openmetadata/server:1.5.6 your-registry/openmetadata/server:1.5.6 # 推送到私有仓库 docker push your-registry/openmetadata/server:1.5.6compose 文件里对应改一行openmetadata_server: image: your-registry/openmetadata/server:1.5.6 # 只换前缀tag 不动tag 一定不能改。1.5.6换成latest或者别的版本服务之间会出现协议不兼容表现出来是迁移失败或者页面 500。改完之后docker-compose config会把渲染后的完整配置打出来顺便校验 YAML 语法比直接 up 然后看报错快。4.4 数据落地与 Elasticsearch 内存两个必须一起调的参数Elasticsearch 默认的 JVM 堆对这台机器来说偏大4G 内存的机器上它一起来就把系统挤爆然后被内核 OOM killer 干掉容器退出码 137。堆参数和虚拟内存映射区两个都要处理。elasticsearch: environment: ES_JAVA_OPTS: -Xms512m -Xmx512m # 4G 机器调到 512m8G 可保持 1g volumes: - ./data/es:/usr/share/elasticsearch/data # 索引目录落到宿主机重建容器不丢-Xms和-Xmx设成相等避免堆在运行中反复扩缩带来的停顿。容器里的目录映射出来之后docker-compose down再 up索引还在不用重新采集。同理可以给 MySQL 加一条./data/mysql:/var/lib/mysql这个我强烈建议加不然手滑down -v一次元数据全没这个后悔药没地方买。宿主机侧还要放开内存映射限制不然 Elasticsearch 启动时 bootstrap checks 直接失败# 临时生效重启机器后回到默认值 sysctl -w vm.max_map_count262144 # 写入配置持久化重启后依然有效 echo vm.max_map_count262144 /etc/sysctl.conf参数值 262144 是 Elasticsearch 要求的下限低于它会拒绝启动。写进/etc/sysctl.conf比只敲临时命令稳容器重启不受影响机器重启也不受影响。5. 避坑记录compose up 之后起不来的五种现场5.1 卡在 Pulling最后报 TLS handshake timeout现象docker-compose -f docker-compose.yml up --detach执行后长时间停在Pulling mysql ...或某个镜像名上几分钟后抛出net/http: TLS handshake timeout容器一个都没起来。原因宿主机访问公共镜像仓库的链路不通或者带宽极低导致握手阶段就超时。这一步和 compose 文件本身没关系配置文件写得再对也拉不下来。解决按 4.3 的方式把镜像逐个搬到私有仓库改 compose 里的image前缀。急的时候可以先在能访问的机器上docker save成 tar 包传过来docker load但长期用还是要有自己的仓库。判断是不是这个问题很简单docker pull单独拉一个基础镜像同样超时就说明是链路问题。5.2 容器全是 Up浏览器打开 8585 还是连不上现象docker ps里openmetadata_server状态 Up宿主机上curl 127.0.0.1:8585有响应但外面浏览器打不开。原因按出现频率排依次是宿主机 firewalld 没放行 8585、端口映射写成了127.0.0.1:8585:8585只绑回环、云环境的安全组没开、以及主服务 JVM 冷启动还没完成。解决先在宿主机上curl -I http://127.0.0.1:8585本机能通就是防火墙或安全组的问题firewall-cmd --list-ports确认本机也不通就看docker-compose logs -f openmetadata_server如果是Started Application之前的日志在滚等一到三分钟JVM 起来没那么快。别看到 Up 就以为服务好了。5.3 executeMigrations 反复重启日志是 Communications link failure现象docker ps -a里迁移容器的状态在Restarting和Exited (1)之间来回跳主服务一直起不来。原因MySQL 容器还处在初始化阶段depends_on只保证启动顺序不保证对方「能用」。迁移脚本连过去时数据库还没准备好接连接直接抛连接失败容器按重启策略再来一次。解决等 MySQL 的日志出现ready for connections再执行 up或者干脆分两步先docker-compose up -d mysql elasticsearchdocker-compose logs -f mysql看到就绪再docker-compose up -d。如果反复失败并且日志是Access denied那就回到 4.1三处密码没对齐。5.4 elasticsearch 起来几十秒就消失退出码 137现象ES 容器启动后一阵子自己没了docker inspect看ExitCode是 137主服务日志里全是索引连接的异常。原因137 是 1289被 SIGKILL 杀掉绝大多数是宿主机内存不足被 OOM killer 选中。第二种可能是vm.max_map_count没调启动阶段 bootstrap checks 失败。解决先free -h看内存水位按 4.4 把ES_JAVA_OPTS调小再dmesg | tail -30确认有没有 OOM 记录有的话就是内存问题无疑。参数没调的执行sysctl -w vm.max_map_count262144。把 ES 和主服务挤在一台 4G 机器上本来就紧把采集任务放到别的机器是更彻底的做法。5.5 登录页提示账号密码错误或者中文显示成问号现象用默认的adminopen-metadata.org登录提示凭据无效或者元数据里的中文描述全变成问号。原因密码在users表里存的是 bcrypt 哈希不是明文直接UPDATE成明文值会导致哈希校验永远失败。中文乱码则是数据库和连接串的字符集不是 utf8mb4。解决忘记密码时不要去改明文用平台提供的重置方式或者在库里写入一段已知密码的 bcrypt 哈希值。字符集方面MySQL 侧建库参数用utf8mb4连接串带上对应参数容器起来之前就把这些定好比事后改表省事得多。这类问题没有捷径只能一开始就配对。6. 装完怎么验证8585 首页到容器健康的三层确认装完就打开浏览器点一遍是我早期最常犯的错——页面能开不代表后台的迁移、索引、采集链路都是通的。后来我固定按三层往下确认任何一层不对就停下来查不往下走。第一层看容器状态和退出码# 看常驻容器是否都在 Up注意 STATUS 里有没有 Restarting docker-compose -f docker-compose.yml ps # 单独看一次性容器迁移容器的期望值是 Exited (0) docker ps -a --filter nameexecuteMigrationsdocker-compose ps比docker ps好用的地方在于它只列这个编排文件里的服务标签和端口一目了然。迁移容器只要是Exited (0)说明表结构已经建完这是主服务能起来的前提。第二层看接口和端口是不是真的通了# 主服务健康检查返回 200 说明 Web 层已经就绪 curl -s -o /dev/null -w %{http_code}\n http://127.0.0.1:8585 # 看最近的启动日志正常会看到 Started Application docker-compose -f docker-compose.yml logs --tail50 openmetadata_server # 确认 ES 索引侧没有报错 docker-compose -f docker-compose.yml logs --tail30 elasticsearch | grep -i errorcurl那条返回000是连不上502一般是反向代理层的问题200才算过关。日志里--tail50只取最后 50 行避免一屏刷完找不到重点。第三层落到页面上逐项过一遍验证项操作期望结果首页可访问浏览器打开http://宿主机IP:8585/出现登录页默认账号可登录adminopen-metadata.org加初始密码进入主界面服务状态设置页看各服务连通性数据库与搜索均为正常数据可见建一个测试库连接或导入示例数据能搜到对应表默认管理员账号是adminopen-metadata.org初始密码在部署文档里有说明第一次登录后立刻改掉别留着默认值跑在能被访问的网段上。改密码走界面里的账号设置别去数据库里直接改字段原因在第 5.5 条说过。页面能打开之后我还会做一件很多人跳过的事docker-compose down再up -d一次确认数据卷挂载生效重启后元数据和账号都还在。这一步花两分钟能提前发现卷没挂对的问题——等平台里录了几百张表的元数据再发现就不是两分钟的事了。从那以后我每次装这类多容器平台都强制走一遍「容器状态 → 接口返回码 → 页面登录 → 重启一致性」这四步不管前面看起来多顺利。装环境这件事能跑起来和能一直跑是两码事前面多花二十分钟后面少熬两个晚上。希望帮到你。本文还有配套的精品资源点击获取