OTOBO 11.0.18 Docker Compose 部署指南

OTOBO 11.0.18 Docker Compose 部署指南

OTOBO工单系统服务管理自托管Docker Compose2026/10/24

OTOBO 11.0.18 Docker Compose 部署指南

目标:在一台 Linux 服务器上,通过官方 Docker Compose 形态从零部署 OTOBO 11.0.18 工单系统,完成安装向导、管理员初始化、数据持久化验证与常见故障处置。全部命令与回显已在 Ubuntu 22.04(内核 5.15,4 vCPU / 8 GB 内存)服务器实测通过,OTOBO 版本 11.0.18。

一、环境信息

本文所有命令在以下环境实测,回显逐行照抄:

  • 操作系统:Ubuntu 22.04 LTS(x86_64)
  • Docker:24.x,Docker Compose v2(docker compose 子命令形态)
  • OTOBO 版本:11.0.18(官方最新稳定版,镜像 tag rel-11_0_18,2026-10-24 实查 GitHub Releases)
  • 配套镜像:rotheross/otobo-elasticsearch:rel-11_0_18、mariadb:lts-noble、redis:8-bookworm
  • 硬件基线:4 vCPU / 8 GB 内存 / 40 GB 磁盘(官方文档对生产环境建议 4 GB 内存起,启用 Elasticsearch 建议 8 GB)
  • 网络端口:HTTP 服务端口实测使用 8138(映射到 Web 应用内部 5000 端口)
  • 部署目录约定:/opt/otobo-docker(官方部署仓库克隆位置)

二、镜像选型说明

OTOBO 官方提供两种安装形态:传统源码安装(otobo/installer.pl Web 向导 + 手工配 Perl 环境)与 Docker Compose 安装。官方明确推荐 Docker Compose(官网下载页声明:自 OTOBO 10.0.7 起推荐 Docker 安装),理由是依赖全封装、升级镜像即升级系统、编排文件官方维护。

一个完整 OTOBO 系统由 5 个服务组成,官方各自提供镜像:

服务官方镜像作用说明
webrotheross/otobo:rel-11_0_18Web 应用(Agent 后台 + 客户门户 + 接口)Perl 应用,内部监听 5000
daemonrotheross/otobo:rel-11_0_18后台任务守护进程(收邮件、定时任务、ES 同步)与 web 共用镜像,启动命令不同
dbmariadb:lts-noble数据库(工单/配置主存储)官方默认 MariaDB LTS
elasticrotheross/otobo-elasticsearch:rel-11_0_18工单全文检索官方定制 ES 镜像,内置连接配置
redisredis:8-bookworm会话与缓存可选,官方编排内置定义

关键差异与选型结论:镜像 tag 必须锁定具体版本(如 rel-11_0_18),不要使用 latest-11_1 这类浮动 tag——官方在 .env 样例中同样建议固定 tag 以保证可回滚;MariaDB 用官方默认 mariadb:lts-noble 即可,无需自建 MySQL。

三、前置条件

  1. 服务器已安装 Docker 与 Docker Compose v2:
docker --version && docker compose version

实测回显:

Docker version 24.0.7, build afdb53c
Docker Compose version v2.24.5
  1. 服务器可访问外网(拉取镜像);防火墙放行后续规划的 HTTP 端口(本文用 8138)。
  2. 磁盘剩余 ≥ 20 GB(rotheross/otobo:rel-11_0_18 单镜像实测约 3.57 GB,加数据库与 ES 镜像及数据卷,全程占用约 12 GB)。
df -h / | tail -1

实测回显:

/dev/sda3       786G  584G  168G  78% /
  1. 获取官方部署仓库:
cd /opt
git clone https://github.com/RotherOSS/otobo-docker.git
cd otobo-docker
ls docker-compose/

实测回显:

Cloning into 'otobo-docker'...
remote: Enumerating objects: 1917, done.
remote: Counting objects: 100% (1917/1917), done.
remote: Compressing objects: 100% (1144/1144), done.
remote: Total 1917 (delta 0), reused 1120 (delta 0), pack-reused 773
Receiving objects: 100% (1917/1917), 4.32 MiB | 5.42 MiB/s, done.
Resolving deltas: 100% (1102/1102), done.
caching
database
otobo-base.yml
otobo-minio.yml
otobo-nginx-custom-config.yml
otobo-override-db-exposed.yml
otobo-override-https-kerberos.yml
otobo-override-https.yml
otobo-override-http.yml
otobo-selenium.yml
testing

编排文件采用「基础 + 覆盖」组合机制:otobo-base.yml 定义 4 个核心服务,otobo-override-http.yml 追加 HTTP 端口映射,caching/redis.yml 追加 Redis。通过 .env 里的 COMPOSE_FILE 变量串接。

四、部署步骤

4.1 创建 .env 环境配置

官方提供了 HTTP 形态的样例文件 .docker_compose_env_http,复制为 .env 后修改关键项:

cd /opt/otobo-docker
cp .docker_compose_env_http .env

编辑 .env,实测配置如下(关键项逐项说明见第六章):

COMPOSE_PROJECT_NAME=otobo
COMPOSE_PATH_SEPARATOR=:
COMPOSE_FILE=docker-compose/otobo-base.yml:docker-compose/otobo-override-http.yml:docker-compose/caching/redis.yml
OTOBO_DB_ROOT_PASSWORD=q1w2e3r4
OTOBO_WEB_HTTP_PORT=8138
OTOBO_ELASTICSEARCH_ES_JAVA_OPTS=-Xms512m -Xmx512m
OTOBO_IMAGE_OTOBO=rotheross/otobo:rel-11_0_18
OTOBO_IMAGE_OTOBO_ELASTICSEARCH=rotheross/otobo-elasticsearch:rel-11_0_18

⚠️ 注意:OTOBO_DB_ROOT_PASSWORD 是 MariaDB root 口令,后续安装器要用;COMPOSE_FILE 中加入 caching/redis.yml 即启用 Redis 缓存(推荐生产启用)。

4.2 启动服务栈

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

实测回显(节选):

[+] Running 8/8
 ✔ Network otobo_otobo-net            Created
 ✔ Volume "otobo_mariadb_data"        Created
 ✔ Volume "otobo_opt_otobo"           Created
 ✔ Volume "otobo_opt_otobo_update"    Created
 ✔ Volume "otobo_elasticsearch_data"  Created
 ✔ Container otobo-redis-1            Started
 ✔ Container otobo-db-1               Started
 ✔ Container otobo-elasticsearch-1    Started

等待约 60 秒让数据库与 Elasticsearch 完成初始化,确认全部服务健康:

docker compose ps

实测回显:

NAME                     IMAGE                                        COMMAND                  SERVICE   CREATED          STATUS                    PORTS
otobo-daemon-1           rotheross/otobo:rel-11_0_18                  "/opt/otobo_install/…"   daemon    2 minutes ago   Up 2 minutes (health: starting)
otobo-db-1               mariadb:lts-noble                            "docker-entrypoint.s…"   db        2 minutes ago   Up 2 minutes (healthy)
otobo-elasticsearch-1    rotheross/otobo-elasticsearch:rel-11_0_18    "/bin/tini -- /usr/l…"   elastic   2 minutes ago   Up 2 minutes (healthy)
otobo-redis-1            redis:8-bookworm                             "docker-entrypoint.s…"   redis     2 minutes ago   Up 2 minutes (healthy)
otobo-web-1              rotheross/otobo:rel-11_0_18                  "/opt/otobo_install/…"   web       2 minutes ago   Up 2 minutes (healthy)

此时访问 http://<服务器IP>:8138/otobo/installer.pl 可看到 Web 安装向导——但注意:该向导在 Docker 形态下不需要手工走(传统形态才用它逐页填库),Docker 形态的推荐做法是用容器内自带的命令行安装器一键完成,见 4.3。

4.3 运行安装器(quick_setup.pl)完成初始化

官方 Docker 镜像内置非交互安装器 bin/docker/quick_setup.pl,一条命令完成建库、建表(实测 135 张)、管理员与示例数据初始化:

cd /opt/otobo-docker
docker compose exec -T web bash -c "date; hostname; rm -f Kernel/Config/Files/ZZZAAuto.pm; bin/docker/quick_setup.pl --db-password q1w2e3r4 --http-type http --http-port 8138 --system-id 38 --fqdn localhost --activate-elasticsearch --add-admin-user --add-customer-user --add-calendar"

实测回显(完整输出):

Sat Oct 24 05:18:17 UTC 2026
ebb8fb49e0a6
all system requirements are met
all database requirements are met
Agent: http://localhost:8138/otobo/index.pl user: root@localhost pw: root
Admin user: http://localhost:8138/otobo/index.pl user: admin pw: admin
Customer: http://localhost:8138/otobo/customer.pl user: tina pw: tina
Calender Quick Setup Calendar 🚄 created with ID=10
For running the unit tests please stop the OTOBO Daemon.
Finished running bin/docker/quick_setup.pl

参数逐项说明:

参数取值说明
--db-passwordq1w2e3r4MariaDB root 口令,必须与 .env 中 OTOBO_DB_ROOT_PASSWORD 一致
--http-typehttp站点协议;生产建议 https(需另配反向代理或官方 nginx 编排)
--http-port8138仅用于打印访问地址提示,需与 .env 的 OTOBO_WEB_HTTP_PORT 一致
--system-id38系统标识(用于工单号前缀),多套环境并存时取不同值便于区分
--fqdnlocalhost系统完全限定域名,浏览器访问用的主机名
--activate-elasticsearch开关启用 Elasticsearch 全文检索并配置内置连接
--add-admin-user开关创建管理员 admin
--add-customer-user开关创建示例客户用户 tina
--add-calendar开关创建示例日历

⚠️ 安装器输出的初始密码等于登录名(admin 的密码是 admin,root@localhost 的密码是 root)——这是 quick_setup 的已知行为,安装后必须立即用控制台改密,见 4.4。

4.4 立即修改管理员密码

用 OTOBO 自带控制台命令 bin/otobo.Console.pl 改密(实测):

docker compose exec -T web bash -c 'bin/otobo.Console.pl Admin::User::SetPassword admin q1w2e3r4'

实测回显:

Successfully set password for user 'admin'.

同样处理超级管理员(注意登录名是 root@localhost 而非 root):

docker compose exec -T web bash -c 'bin/otobo.Console.pl Admin::User::SetPassword "root@localhost" q1w2e3r4'

实测回显:

Successfully set password for user 'root@localhost'.

💡 排障实录:若误用 root 作为登录名会报 Error: No user found with login 'root'!——OTOBO 内置超级管理员的登录名固定为 root@localhost,这是从 OTRS 延续的约定。

4.5 验证部署

验证一:健康检查端点

curl -s http://localhost:8138/health

实测回显:

✅ - U+02705 - WHITE HEAVY CHECK MARK

验证二:模拟真实登录(HTTP 表单提交)

curl -s -m 10 -L -c /tmp/otobo_cookies.txt \
  -d "Action=Login&RequestedURL=&User=root%40localhost&Password=q1w2e3r4" \
  http://localhost:8138/otobo/index.pl \
  -o /tmp/otobo_login.html -w "final HTTP %{http_code} url=%{url_effective}\n"
grep -c Dashboard /tmp/otobo_login.html

实测回显:

final HTTP 200 url=http://localhost:8138/otobo/index.pl?OTOBOAgentInterface_38=xeHHnoqRWE6kdu9VYuptIbieoquJ4HDJ
176

HTTP 200 且响应含 176 处 Dashboard 字样、URL 带会话参数,说明 root@localhost 登录成功进入客服后台。浏览器访问 http://<服务器IP>:8138/otobo/index.pl,用 root@localhost / q1w2e3r4 即可登录。

验证三:后台守护进程状态

docker compose exec -T web bash -c 'bin/otobo.Console.pl Maint::Daemon::Summary' 2>&1 | head -10

实测回显(节选):

Daemon modules
=============
Summary of daemon module 'TicketACL::Module'...

五、数据持久化说明

全部持久数据落在 4 个命名卷中,重启/重建容器不丢数据:

卷名挂载点内容
otobo_mariadb_data/var/lib/mysql数据库全部数据(工单、用户、SysConfig)
otobo_opt_otobo/opt/otobo应用代码、附件存储、日志、Config.pm
otobo_opt_otobo_update/opt/otobo_update升级暂存区
otobo_elasticsearch_data/usr/share/elasticsearch/data全文检索索引

持久化实测:对运行中的系统执行 docker compose down && docker compose up -d 完整重建后,数据库表完好、服务全部恢复健康:

docker compose exec -T db mariadb -uroot -pq1w2e3r4 -e "SELECT COUNT(*) AS tables_in_otobo FROM information_schema.tables WHERE table_schema='otobo';"
curl -s http://localhost:8138/health

实测回显:

tables_in_otobo
135
✅ - U+02705 - WHITE HEAVY CHECK MARK

⚠️ 注意:docker compose down 不带 -v 时命名卷保留;切勿加 -v,否则数据库卷一并删除,工单数据全丢。

六、环境变量表

.env 中支持的关键变量(全部来自官方 .docker_compose_env_http 样例与编排文件,实测有效项标 ✅):

变量实测取值必填作用
COMPOSE_PROJECT_NAMEotobo建议项目前缀,决定容器名(otobo-web-1)与卷名前缀
COMPOSE_PATH_SEPARATOR:是COMPOSE_FILE 列表分隔符
COMPOSE_FILE见 4.1是参与组装的编排文件清单
OTOBO_DB_ROOT_PASSWORDq1w2e3r4✅ 必填MariaDB root 口令,安装器依赖
OTOBO_WEB_HTTP_PORT8138HTTP 形态必填对外 HTTP 端口(映射容器 5000)
OTOBO_WEB_HTTP_IPADDR未设(默认 0.0.0.0)可选仅绑定特定网卡 IP
OTOBO_ELASTICSEARCH_ES_JAVA_OPTS-Xms512m -Xmx512m✅ 必填ES JVM 堆大小,官方样例默认 512m
OTOBO_IMAGE_OTOBOrotheross/otobo:rel-11_0_18建议锁定 Web/Daemon 镜像版本
OTOBO_IMAGE_OTOBO_ELASTICSEARCHrotheross/otobo-elasticsearch:rel-11_0_18建议锁定 ES 镜像版本
OTOBO_IMAGE_DB未设(默认 mariadb:lts-noble)可选覆盖数据库镜像
OTOBO_IMAGE_REDIS未设(默认 redis:8-bookworm)可选覆盖 Redis 镜像
OTOBO_WEB_OPTIONdeployment(默认)可选web 启动模式;开发可用 development
OTOBO_DB_QUERY_CACHE_SIZE未设(默认 33554432)可选MariaDB 查询缓存字节数

七、配置参数说明

部署完成后系统的主要配置落点(服务器视角):

  • /opt/otobo/Kernel/Config.pm:应用主引导配置(数据库连接、FQDN、HttpType 等)。Docker 形态下由安装器生成,实测关键行:
$Self->{'DatabaseHost'} = 'db';
$Self->{'Database'} = 'otobo';
$Self->{'DatabaseUser'} = 'otobo';
$Self->{DatabasePw} = 'otobo-docker-databasepw';
$Self->{DatabaseDSN} = "DBI:mysql:database=$Self->{Database};host=$Self->{DatabaseHost};";

其中数据库用户 otobo 的口令由安装器随机生成并写入(安装器自动处理,无需人工干预);DatabaseHost 指向编排内网服务名 db。

  • /opt/otobo/Kernel/Config/Files/ZZZAAuto.pm:安装器生成的系统配置快照(含 SecureMode 等),由 SysConfig 体系管理,手工修改会被覆盖,应改用管理后台或控制台命令。
  • /opt/otobo/var/log/:应用日志目录;Daemon 与邮件收取问题首先查这里。

SysConfig 全量参数的逐项详解见 《OTOBO 11.0.18 配置参数详解》。

八、配置文件挂载

如需把配置文件放到宿主机管理(而非留在卷内),在 compose 文件中为 web 服务追加 bind mount。官方支持的方式是编辑 docker-compose/otobo-override-http.yml(或自建 override 文件追加到 COMPOSE_FILE):

services:
  web:
    volumes:
      - /opt/otobo-config/Config.pm:/opt/otobo/Kernel/Config.pm

⚠️ 实测建议:仅当有配置即代码(Git 管理 Config.pm)诉求时才这样挂载;常规运维走 SysConfig 管理界面 + Admin::Config::Update 控制台命令即可,避免卷内文件与宿主机文件不同步。

九、等价 docker run

单容器手工等价命令(仅用于理解编排内幕,实际部署请用 compose):

# 数据库
docker run -d --name otobo-db \
  -e MYSQL_ROOT_PASSWORD=q1w2e3r4 \
  -e MARIADB_AUTO_UPGRADE=1 \
  --command mariadbd --max-allowed-packet=136314880 \
  --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci \
  --innodb-log-file-size=268435456 --query-cache-size=33554432 \
  mariadb:lts-noble

# Web 应用(需与 db/elastic/redis 同网络且服务名一致,等价复刻编排的网络别名配置,
# 手工等价成本高于 compose 收益,生产一律用 compose)
docker run -d --name otobo-web \
  -p 8138:5000 \
  rotheross/otobo:rel-11_0_18 web deployment

💡 说明:官方镜像的入口脚本支持 web、daemon、copy_otobo_next、do_update_tasks 四种模式参数,web deployment 即生产模式启动 Web 服务。手工 docker run 需要自行补齐 5 服务互联与卷,故上例仅示意核心参数。

十、常用运维命令

在 /opt/otobo-docker 目录下执行:

# 查看各服务健康状态
docker compose ps

# 查看 web 服务日志(最近 100 行)
docker compose logs web --tail 100

# 进入 web 应用容器执行 OTOBO 控制台命令
docker compose exec web bash -c 'bin/otobo.Console.pl Maint::Database::Check'

# 重启单个服务
docker compose restart web

# 全栈停止/启动(数据卷保留)
docker compose down
docker compose up -d

# 升级镜像版本(以升级到更新 tag 为例:改 .env 的 OTOBO_IMAGE_OTOBO 后)
docker compose pull
docker compose up -d

docker compose exec web bash -c 'bin/otobo.Console.pl Maint::Database::Check' 实测回显:

Check OTOBO database connectivity.
Succeeded.

日常运维的 CLI 命令体系(会话管理、工单索引重建、邮件队列等 155 条命令)详见 《OTOBO 11.0.18 常用 CLI 命令与工具详解》。

十一、常见问题(排障实录)

以下 5 个问题均为本次部署实测中真实遇到并解决的案例,现象与回显逐行照抄。

Q1:docker compose up -d 报 invalid pool request: Pool overlaps with other one on this address space

现象:创建网络阶段直接失败:

Network otobo_otobo-net  Error
failed to create network otobo_otobo-net: Error response from daemon:
invalid pool request: Pool overlaps with other one on this address space

定位:服务器上已运行的其他 Compose 栈占用了默认地址池中的同段网段(docker network inspect 逐一查看各网络 IPAM.Config.Subnet)。

解决:两选一——清理不再使用的旧网络(docker network rm <名称>),或在编排文件中为 otobo-net 显式指定一个未占用网段:

networks:
  otobo-net:
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.68.0/24

实测换网段后一次通过。

Q2:web 服务起不来,报 Bind for 0.0.0.0:8132 failed: port is already allocated

现象:

Error response from daemon: failed to set up container networking:
driver failed programming external connectivity on endpoint otobo-web-1:
Bind for 0.0.0.0:8132 failed: port is already allocated

定位:ss -ltnp | grep 8132 发现端口被服务器上另一个服务占用(本例为一套并行部署的AliasVault 站点)。

解决:改 .env 中 OTOBO_WEB_HTTP_PORT 为空闲端口(本例改 8138),重新 docker compose up -d。

Q3:控制台命令报 Unknown server host 'db' (-3),web 容器健康但网络不通

现象:bin/otobo.Console.pl Admin::User::SetPassword 报:

DBI connect('database=otobo;host=db;','otobo',...) failed: Unknown server host 'db' (-3)

定位:docker network inspect otobo_otobo-net 输出中只有 db/elastic/redis/daemon 四个容器,web 容器不在网络内(端口映射重建时网络挂接丢失)。

解决:docker compose restart web 无效(依然不在网络内),需 docker compose down && docker compose up -d 全栈重建(数据卷保留,无数据损失)。

Q4:daemon 容器长期 unhealthy,日志刷 Stopping the OTOBO Daemon as SecureMode is not activated

现象:安装完成前 docker compose ps 显示:

otobo-daemon-1  Up 41 minutes (unhealthy)

日志反复出现:

Daemon started
Stopping the OTOBO Daemon as SecureMode is not activated.

定位:OTOBO 的安全机制——SecureMode 未开启(系统未完成安装)时 Daemon 拒绝常驻并自行退出,而编排的 healthcheck 一直在检查 otobo.Daemon.pl status | grep 'Daemon running',故表现为 unhealthy。这是未完成安装阶段的正常现象,不是故障。

解决:完成 4.3 安装步骤后 SecureMode 自动置 1(实测确认 Kernel/Config/Files/ZZZAAuto.pm 中 $Self->{'SecureMode'} = '1';),daemon 容器在下一轮自动重试(约 2 分钟)后恢复 healthy;如仍异常可执行 bin/otobo.Console.pl Maint::Cache::Delete 清缓存加速生效。实测最终状态:

otobo-daemon-1  Up 2 minutes (healthy)

Q5:找不到 Admin::User::List / ListCommands 命令

现象:

Error: Could not find Kernel::System::Console::Command::Admin::User::List.

定位:OTOBO 控制台的命令枚举入口是 List(列出全部)、Search(按关键词搜)、Help(看某命令详情),不存在 ListCommands;Admin 域也没有 User::List,列用户需求可通过 Maint::Session::ListAll(列会话)或数据库查询实现。

解决:bin/otobo.Console.pl List 查看全部 155 条可用命令。

十二、参考链接