Apache Unomi 3.0.1 Docker Compose 部署指南

使用 Docker Compose 一键部署 Apache Unomi 3.0.1 与 Elasticsearch 9.5.3:提供自建镜像的 Dockerfile 与入口脚本、编排文件、数据持久化、环境变量表与常用运维命令,全程实测。

Apache UnomiApache Unomi2026/10/12

Apache Unomi 3.0.1 Docker Compose 部署指南

本文介绍以 Docker Compose 编排部署 Apache Unomi 3.0.1 与 Elasticsearch 9.5.3 的完整方案,包含自建镜像、编排文件、持久化与运维命令。全部文件与命令均在真实环境实测通过。

一、环境信息

项目说明
Apache Unomi3.0.1(自建镜像 unomi-local:3.0.1,实测 961MB)
Elasticsearch9.5.3(官方镜像 docker.elastic.co/elasticsearch/elasticsearch:9.5.3,实测 2.56GB)
基础镜像eclipse-temurin:17-jre(Unomi 运行时)
Docker / Compose引擎 20.10+,Compose v2(实测版本 docker 29.8.0)
部署目录/opt/unomi-compose
端口映射8181(cxs HTTP)、9443(cxs HTTPS)、9200(ES HTTP)、8102(Karaf 控制台,可选)
管理账号karaf / q1w2e3r4

二、镜像选型说明

  • Elasticsearch 直接使用官方镜像 docker.elastic.co/elasticsearch/elasticsearch:9.5.3。
  • Apache Unomi 官方 Docker 仓库(apache/unomi)当前最新版本为 2.6.1,尚未提供 3.0.1 镜像;而 Unomi 3.0.1 要求 Elasticsearch 版本窗口 9.0.3-10.0.0 与 JDK 17。因此本文采用自建镜像方案:以 eclipse-temurin:17-jre 为基础,叠加官方发行包与启动入口脚本,构建 unomi-local:3.0.1。
  • 自建镜像内置的入口脚本完成两件事:等待 Elasticsearch 健康后以前台模式启动 Karaf;循环执行 unomi:start 完成首次初始化。这与裸机部署的关键差异在于:初始化无需人工介入。

三、前置条件

  1. 宿主机已安装 Docker 引擎与 Compose v2 插件(docker compose version 可正常输出)。
  2. 宿主机内核参数满足 ES 要求,执行并持久化:
sysctl -w vm.max_map_count=262144
echo "vm.max_map_count = 262144" > /etc/sysctl.d/99-elasticsearch.conf
  1. 磁盘可用空间不低于 4GB(两份镜像合计约 3.5GB,另需索引数据空间)。
  2. 已下载官方发行包 unomi-3.0.1-bin.tar.gz(https://dlcdn.apache.org/unomi/3.0.1/unomi-3.0.1-bin.tar.gz),SHA512 校验值:
99e1d9f729eb4adfe9288fdfd9d1ec6a35489dfa8c17e7658c1a08ceb550b1bca31646355c043cf59a926cca7f2a00d692d7ce59d95b318e1baaf11c311f1cc9
  1. 宿主机 8181、9443、9200 端口未被占用。

四、部署步骤

4.1 准备构建目录

mkdir -p /opt/unomi-compose

将 unomi-3.0.1-bin.tar.gz 放入 /opt/unomi-compose,并校验:

cd /opt/unomi-compose
sha512sum unomi-3.0.1-bin.tar.gz

回显应与第三节校验值一致。

4.2 编写 Dockerfile

在 /opt/unomi-compose 创建 Dockerfile:

FROM eclipse-temurin:17-jre
ADD unomi-3.0.1-bin.tar.gz /opt/
RUN mv /opt/unomi-3.0.1 /opt/unomi
COPY entrypoint.sh /opt/unomi/bin/entrypoint.sh
RUN chmod 755 /opt/unomi/bin/entrypoint.sh
WORKDIR /opt/unomi
EXPOSE 8181 9443 8102
ENTRYPOINT ["/opt/unomi/bin/entrypoint.sh"]

4.3 编写入口脚本 entrypoint.sh

在 /opt/unomi-compose 创建 entrypoint.sh:等待 ES 健康后前台启动 Karaf,并循环尝试执行 unomi:start 直至成功(首次初始化约需数分钟):

#!/bin/bash
schema='http'
if [ "$UNOMI_ELASTICSEARCH_SSL_ENABLE" = 'true' ]; then schema='https'; fi
health_url="$schema://${UNOMI_ELASTICSEARCH_ADDRESSES:-localhost:9200}/_cat/health?h=status"
health_check="$(curl -fsSL "$health_url" 2>/dev/null)"
until [ "$health_check" = 'yellow' ] || [ "$health_check" = 'green' ]; do
    health_check="$(curl -fsSL "$health_url" 2>/dev/null)"
    >&2 echo "Elasticsearch is not yet available - waiting (health check=$health_check)..."
    sleep 2
done
/opt/unomi/bin/karaf server &
KARAF_PID=$!
i=0
until echo "unomi:start" | timeout 30 /opt/unomi/bin/client -u karaf -p "${UNOMI_ROOT_PASSWORD:-karaf}" >/dev/null 2>&1; do
    i=$((i + 1))
    if [ "$i" -ge 120 ]; then >&2 echo "unomi:start failed"; kill "$KARAF_PID"; exit 1; fi
    sleep 5
done
>&2 echo "Apache Unomi services started"
wait "$KARAF_PID"

注意 client 调用必须携带 -u karaf -p 凭据(默认密码 karaf,与 UNOMI_ROOT_PASSWORD 保持一致)。

4.4 构建镜像

docker build -t unomi-local:3.0.1 /opt/unomi-compose

构建完成后确认:

docker images unomi-local

实测回显:

REPOSITORY   TAG      IMAGE ID       CREATED         SIZE
unomi-local  3.0.1    ab3318894cc1   2 hours ago     961MB

4.5 编写 docker-compose.yml

在 /opt/unomi-compose 创建 docker-compose.yml:

services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:9.5.3
    container_name: unomi-elasticsearch
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - cluster.name=contextElasticSearch
      - ES_JAVA_OPTS=-Xms512m -Xmx512m
    ports:
      - "9200:9200"
    volumes:
      - es-data:/usr/share/elasticsearch/data
    healthcheck:
      test: ["CMD-SHELL", "curl -sf http://localhost:9200/_cluster/health || exit 1"]
      interval: 15s
      timeout: 10s
      retries: 10
  unomi:
    image: unomi-local:3.0.1
    container_name: unomi-server
    environment:
      - UNOMI_ROOT_PASSWORD=q1w2e3r4
      - UNOMI_ELASTICSEARCH_ADDRESSES=elasticsearch:9200
      - EXTRA_JAVA_OPTS=-Xms256M -Xmx512M -Dorg.apache.unomi.elasticsearch.sslEnable=false
    ports:
      - "8181:8181"
      - "9443:9443"
      - "8102:8102"
    depends_on:
      elasticsearch:
        condition: service_healthy
volumes:
  es-data:

要点说明:ES 集群名必须为 contextElasticSearch(Unomi 默认连接值);xpack.security.enabled=false 与 Unomi 默认无认证连接匹配;EXTRA_JAVA_OPTS 同时限定 Unomi 堆内存 256-512MB 并通过系统属性关闭 ES SSL 连接(发行包 cfg 默认 sslEnable=true,实测必须覆盖);unomi 服务以 condition: service_healthy 等待 ES 就绪后再启动。

4.6 启动编排

cd /opt/unomi-compose
docker compose up -d

查看状态(ES 需先通过 healthcheck):

docker compose ps

实测回显:

NAME                  IMAGE                                                SERVICE         STATUS
unomi-elasticsearch   docker.elastic.co/elasticsearch/elasticsearch:9.5.3  elasticsearch   Up (healthy)
unomi-server          unomi-local:3.0.1                                    unomi           Up

4.7 确认初始化完成

docker compose logs unomi | tail -3

实测回显关键行:

Apache Unomi services started

首次启动含 unomi:start 初始化,从 up 到该日志出现通常需要 3-8 分钟,期间 unomi-server 日志会反复输出 Elasticsearch 等待信息属正常现象。

4.8 验证部署

在 unomi-server 内调用 cxs REST 接口(请求体必须携带 sessionId):

docker exec unomi-server curl -s -o /dev/null -w '%{http_code}\n' -X POST http://127.0.0.1:8181/cxs/context.json -H 'Content-Type: application/json' -d '{"source":{"itemId":"home","itemType":"page","scope":"mysite"},"sessionId":"compose-session-001"}'

实测回显:

200

验证 HTTPS 集群接口(自签证书加 -k,Basic 认证使用 karaf / q1w2e3r4):

docker exec unomi-server curl -sk -u karaf:q1w2e3r4 -o /dev/null -w '%{http_code}\n' https://localhost:9443/cxs/cluster

实测回显:

200

宿主机与外部客户端直接访问 http://<服务器IP>:8181/cxs/context.json 同样可用(端口已映射)。

五、数据持久化说明

  • Elasticsearch 数据(画像、事件、会话等全部业务数据)保存在命名卷 es-data(挂载于 /usr/share/elasticsearch/data),执行 docker compose down 不会删除,docker compose down -v 会连卷删除——生产环境慎用。
  • unomi-server 内 /opt/unomi/data 仅包含 Karaf 运行缓存(felix cache)与日志,不存业务数据;重建 unomi 容器不丢失用户数据,入口脚本会在每次启动时自动重新完成 unomi:start 初始化(实测幂等)。
  • 数据卷由 Compose 按项目命名管理(卷名带项目前缀),执行 docker volume ls 查看;备份时挂载该卷打包即可,例如启动一个临时工具镜像挂载卷后执行 tar。

六、常用环境变量表

Unomi 镜像通过 custom.system.properties 内置的 ${env:UNOMI_XXX:-默认值} 映射支持环境变量注入(实测清单节选):

环境变量说明默认值
UNOMI_ROOT_PASSWORDKaraf 管理账号 karaf 的密码karaf
UNOMI_HTTP_PORTcxs HTTP 端口8181
UNOMI_SECURE_HTTP_PORTcxs HTTPS 端口9443
UNOMI_ELASTICSEARCH_ADDRESSESES 地址(Compose 中为服务名 elasticsearch:9200)localhost:9200
UNOMI_ELASTICSEARCH_CLUSTERNAMEES 集群名contextElasticSearch
UNOMI_ELASTICSEARCH_USERNAME / UNOMI_ELASTICSEARCH_PASSWORDES 认证账号空
UNOMI_ELASTICSEARCH_SSL_ENABLE连接 ES 是否走 HTTPS(入口脚本据此选择健康检查协议)—
UNOMI_ELASTICSEARCH_INDEXPREFIX索引名前缀context
UNOMI_CLUSTER_PUBLIC_ADDRESS对外公布地址http://localhost:8181
UNOMI_CLUSTER_INTERNAL_ADDRESS节点间通信地址https://localhost:9443
UNOMI_CLUSTER_NODEID节点 ID,多实例部署每份编排必须唯一unomi-node-1
ES_JAVA_OPTSES 官方镜像 JVM 参数(本文设 512m 堆)—
EXTRA_JAVA_OPTSUnomi JVM 附加参数(本文设堆 256-512MB 并关闭 ES SSL 属性)—

七、常用配置参数说明

  • 配置注入链路:环境变量 UNOMI_XXX → custom.system.properties 的 ${env:UNOMI_XXX:-默认值} → Karaf 系统属性 → etc/*.cfg 的属性替换。修改环境变量后执行 docker compose up -d --force-recreate unomi 重建生效。
  • EXTRA_JAVA_OPTS 中的 -Dorg.apache.unomi.elasticsearch.sslEnable=false 作用:发行包 cfg 中 sslEnable 的属性替换默认值为 true,系统属性优先级高于 cfg 默认值,实测以此方式关闭对 ES 的 HTTPS 连接。若自建镜像时已将 cfg 改为字面值 false,则该 -D 参数可省略。
  • ES 侧参数通过 environment 直接注入官方镜像:discovery.type、xpack.security.enabled、cluster.name、ES_JAVA_OPTS,均实测有效。

八、配置文件持久化

如需深度定制,可仅挂载具体 cfg 文件到 unomi 容器(fileinstall 会监控加载),例如覆盖 ES 连接配置:

  unomi:
    volumes:
      - ./org.apache.unomi.persistence.elasticsearch.cfg:/opt/unomi/etc/org.apache.unomi.persistence.elasticsearch.cfg:ro

也可以同样方式挂载 users.properties 注入账号密码。

重要警告(实测踩坑):不要挂载覆盖 /opt/unomi/etc/custom.system.properties——该文件包含端口定义(8181/9443)与全部 UNOMI_* 环境变量映射,覆盖后 HTTP 端口回落为 8080 且环境变量全部失效,8181 将无法访问。定制该文件时应先 docker cp unomi-server:/opt/unomi/etc/custom.system.properties . 取出原文件、修改后再整体挂载回去。

ES 侧如需固定 elasticsearch.yml,可从官方镜像取出 /usr/share/elasticsearch/config/elasticsearch.yml 修改后挂载。

九、等价 docker run 运行方式

不使用 Compose 时,以下命令与上述编排完全等价(实测组网逻辑一致):

docker network create unomi-net
docker run -d --name unomi-elasticsearch --network unomi-net -p 9200:9200 -e discovery.type=single-node -e xpack.security.enabled=false -e cluster.name=contextElasticSearch -e ES_JAVA_OPTS="-Xms512m -Xmx512m" -v unomi-es-data:/usr/share/elasticsearch/data docker.elastic.co/elasticsearch/elasticsearch:9.5.3
docker run -d --name unomi-server --network unomi-net -p 8181:8181 -p 9443:9443 -p 8102:8102 -e UNOMI_ROOT_PASSWORD=q1w2e3r4 -e UNOMI_ELASTICSEARCH_ADDRESSES=elasticsearch:9200 -e EXTRA_JAVA_OPTS="-Xms256M -Xmx512M -Dorg.apache.unomi.elasticsearch.sslEnable=false" unomi-local:3.0.1

十、常用运维命令

docker compose ps
docker compose logs -f unomi
docker compose logs -f elasticsearch
docker compose restart unomi
docker compose stop
docker compose up -d
docker compose images

进入 Unomi 排障:

docker exec -it unomi-server /opt/unomi/bin/client -u karaf -p q1w2e3r4

进入后可执行 system:version、bundle:list、log:display 等 Karaf 命令,Ctrl+D 退出。完全下线并删除数据卷(危险,业务数据会丢失)使用 docker compose down -v。

十一、常见问题

**Q1:**unomi-server 一直输出 Elasticsearch is not yet available - waiting? 入口脚本在等 ES 健康。检查 elasticsearch 容器状态与日志:常见原因是宿主机 vm.max_map_count 低于 262144 导致 ES 启动失败,或 cluster.name 与 Unomi 侧不一致。宿主机执行 sysctl -w vm.max_map_count=262144 后 docker compose restart elasticsearch。

**Q2:**宿主机访问 8181 无响应,但容器内 8080 有服务? 挂载覆盖了 /opt/unomi/etc/custom.system.properties,端口定义与环境变量映射丢失所致。按第八节警告处理:恢复该文件或改为仅挂载具体 cfg 文件。

**Q3:**POST /cxs/context.json 返回 internalServerError? Unomi 3.x 要求请求体携带 sessionId、profileId 或 personaId 之一,补齐 "sessionId":"demo-session-001" 后返回 200 并回显 profileId。

**Q4:**ES 启动失败,日志报 max virtual memory areas vm.max_map_count [65530] is too low? 在宿主机(而非容器内)执行内核参数调整并重启 ES 服务,见第三节与 Q1。

**Q5:**bin/client 连接报 Closed 或认证失败? 系统未完全启动时连接会被拒绝,等待初始化完成(日志出现 Apache Unomi services started);认证失败检查 UNOMI_ROOT_PASSWORD 与 -p 参数是否一致。

**Q6:**能否直接使用官方 apache/unomi:2.6.1 镜像? 可以,但那是 2.x 功能集:要求 JDK 11、ES 7.x/8.x,配置项与本篇 3.0.1 方案存在差异,需按 2.x 官方手册核对;需要 3.0.1 能力时仍应采用本文自建镜像方案。

**Q7:**如何调整 Unomi 堆内存? 修改 compose 中 EXTRA_JAVA_OPTS 的 -Xms/-Xmx(建议保持 256-512MB 区间)后执行 docker compose up -d --force-recreate unomi,并在容器内以 ps -ef | grep karaf.main.Main 验证回显中的堆参数。

十二、参考链接