OTOBO 11.0.18 Docker Compose 部署指南
OTOBO 11.0.18 Docker Compose 部署指南
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 个服务组成,官方各自提供镜像:
| 服务 | 官方镜像 | 作用 | 说明 |
|---|---|---|---|
| web | rotheross/otobo:rel-11_0_18 | Web 应用(Agent 后台 + 客户门户 + 接口) | Perl 应用,内部监听 5000 |
| daemon | rotheross/otobo:rel-11_0_18 | 后台任务守护进程(收邮件、定时任务、ES 同步) | 与 web 共用镜像,启动命令不同 |
| db | mariadb:lts-noble | 数据库(工单/配置主存储) | 官方默认 MariaDB LTS |
| elastic | rotheross/otobo-elasticsearch:rel-11_0_18 | 工单全文检索 | 官方定制 ES 镜像,内置连接配置 |
| redis | redis:8-bookworm | 会话与缓存 | 可选,官方编排内置定义 |
关键差异与选型结论:镜像 tag 必须锁定具体版本(如 rel-11_0_18),不要使用 latest-11_1 这类浮动 tag——官方在 .env 样例中同样建议固定 tag 以保证可回滚;MariaDB 用官方默认 mariadb:lts-noble 即可,无需自建 MySQL。
三、前置条件
- 服务器已安装 Docker 与 Docker Compose v2:
docker --version && docker compose version
实测回显:
Docker version 24.0.7, build afdb53c
Docker Compose version v2.24.5
- 服务器可访问外网(拉取镜像);防火墙放行后续规划的 HTTP 端口(本文用 8138)。
- 磁盘剩余 ≥ 20 GB(
rotheross/otobo:rel-11_0_18单镜像实测约 3.57 GB,加数据库与 ES 镜像及数据卷,全程占用约 12 GB)。
df -h / | tail -1
实测回显:
/dev/sda3 786G 584G 168G 78% /
- 获取官方部署仓库:
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-password | q1w2e3r4 | MariaDB root 口令,必须与 .env 中 OTOBO_DB_ROOT_PASSWORD 一致 |
--http-type | http | 站点协议;生产建议 https(需另配反向代理或官方 nginx 编排) |
--http-port | 8138 | 仅用于打印访问地址提示,需与 .env 的 OTOBO_WEB_HTTP_PORT 一致 |
--system-id | 38 | 系统标识(用于工单号前缀),多套环境并存时取不同值便于区分 |
--fqdn | localhost | 系统完全限定域名,浏览器访问用的主机名 |
--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_NAME | otobo | 建议 | 项目前缀,决定容器名(otobo-web-1)与卷名前缀 |
COMPOSE_PATH_SEPARATOR | : | 是 | COMPOSE_FILE 列表分隔符 |
COMPOSE_FILE | 见 4.1 | 是 | 参与组装的编排文件清单 |
OTOBO_DB_ROOT_PASSWORD | q1w2e3r4 | ✅ 必填 | MariaDB root 口令,安装器依赖 |
OTOBO_WEB_HTTP_PORT | 8138 | HTTP 形态必填 | 对外 HTTP 端口(映射容器 5000) |
OTOBO_WEB_HTTP_IPADDR | 未设(默认 0.0.0.0) | 可选 | 仅绑定特定网卡 IP |
OTOBO_ELASTICSEARCH_ES_JAVA_OPTS | -Xms512m -Xmx512m | ✅ 必填 | ES JVM 堆大小,官方样例默认 512m |
OTOBO_IMAGE_OTOBO | rotheross/otobo:rel-11_0_18 | 建议 | 锁定 Web/Daemon 镜像版本 |
OTOBO_IMAGE_OTOBO_ELASTICSEARCH | rotheross/otobo-elasticsearch:rel-11_0_18 | 建议 | 锁定 ES 镜像版本 |
OTOBO_IMAGE_DB | 未设(默认 mariadb:lts-noble) | 可选 | 覆盖数据库镜像 |
OTOBO_IMAGE_REDIS | 未设(默认 redis:8-bookworm) | 可选 | 覆盖 Redis 镜像 |
OTOBO_WEB_OPTION | deployment(默认) | 可选 | 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 条可用命令。
十二、参考链接
- 官方 Docker 安装手册:https://doc.otobo.org/manual/installation/11.0/en/content/installation/installation-docker.html
- 官方部署仓库:https://github.com/RotherOSS/otobo-docker
- Docker Hub 镜像:https://hub.docker.com/repository/docker/rotheross/otobo
- 版本实查(GitHub Tags):https://github.com/RotherOSS/otobo/tags
- 本专栏相关文档:《OTOBO 11.0.18 介绍与选型指南》、《OTOBO 11.0.18 配置参数详解》、《OTOBO 11.0.18 常用 CLI 命令与工具详解》