Frappe Helpdesk 1.31 Docker Compose 部署指南
使用 Frappe 官方 frappe_docker 编排以 Docker Compose 部署 Helpdesk 1.31.0 的实测指南:镜像选型、.env 与 override 组织、建站加固、持久化与备份恢复闭环、环境变量表、日常运维与排障实录。
Frappe Helpdesk 1.31 Docker Compose 部署指南
目标:在一台装好 Docker 的 Ubuntu 服务器上,使用 Frappe 官方编排仓库 frappe_docker 以 Docker Compose 部署 Frappe Helpdesk 1.31.0 生产栈,覆盖镜像选型、编排文件组织、建站、持久化验证、备份恢复闭环、日常运维与卸载。文中所有命令与回显均为 2026-10-23 在 Docker 29.8.0 + Compose v5.5.1 环境实测的原始输出。产品定位见[《Frappe Helpdesk 1.31 介绍与选型指南》](https://www.quzuo.net/document/xtxb3uZrBRAB),bench 手工路径见本专栏安装指南篇。
一、环境信息
| 项目 | 实测值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS |
| Docker Engine | 29.8.0 |
| Docker Compose | v5.5.1(docker compose version 实查) |
| 编排仓库 | github.com/frappe/frappe_docker(main 分支,2026-10-23 克隆) |
| Helpdesk 镜像 | ghcr.io/frappe/helpdesk:stable |
| MariaDB 镜像 | mariadb:11.8(官方编排 compose.mariadb.yaml 指定) |
| Redis 镜像 | redis:8.6-alpine(官方编排 compose.redis.yaml 指定) |
| 栈内应用版本 | frappe 15.123.1 / helpdesk 1.31.0 / telephony 0.0.1(bench version 实查) |
| Compose 项目名 | frappe-helpdesk-1-31-0-stack |
说明:Helpdesk 官方 README 的生产部署推荐 easy-install.py 一键脚本(内部同样拉起 frappe_docker 编排);本文采用手工组织 compose 文件的方式,与脚本产物同构,但每一步可控可复盘。
二、镜像选型
2.1 官方镜像
Frappe 官方在 GitHub Container Registry 发布 Helpdesk 应用镜像:ghcr.io/frappe/helpdesk。该镜像内含 Frappe 框架、helpdesk 与 telephony 应用(bench version 实测回显):
frappe 15.123.1
helpdesk 1.31.0
telephony 0.0.1
标签选择:
| 标签 | 含义 | 适用 |
|---|---|---|
stable | 跟随最新稳定版(撰写本文时即 1.31.0,与官方 easy-install 文档 --version=stable 一致) | 生产推荐 |
v1.31.0 等具体版本号 | 锁定版本 | 需要版本固定、灰度回退 |
develop | 开发分支 | 测试尝鲜,勿用于生产 |
2.2 依赖镜像
来自 frappe_docker 官方 override 文件(实查原文),无需自行选型:
mariadb:11.8(overrides/compose.mariadb.yaml,带 healthcheck 与MARIADB_AUTO_UPGRADE: 1)redis:8.6-alpine(overrides/compose.redis.yaml,cache 与 queue 各一实例)
⚠️ 实测提示:网上旧资料常见 mariadb:10.6 + redis:6.2 组合,现行 frappe_docker main 分支已升级为上表组合。Frappe Framework 恢复数据时会提示 Warning: MariaDB version ['11.8', '9'] is more than 10.8 which is not yet tested with Frappe Framework.——属官方已知警告,功能可正常使用(本文备份恢复实测通过)。
三、前置条件
docker --version
# Docker version 29.8.0
docker compose version
# Docker Compose version v5.5.1
准备编排目录(示例规划 /opt/frappe-helpdesk,可按需调整):
git clone --depth 1 https://github.com/frappe/frappe_docker.git
mkdir -p /opt/frappe-helpdesk && cd /opt/frappe-helpdesk
cp ~/frappe_docker/compose.yaml .
cp -r ~/frappe_docker/overrides .
⚠️ 若服务器访问 GitHub/GHCR 缓慢或失败,先为当前会话配置代理(export http_proxy=... https_proxy=...)或为 Docker 守护进程配置镜像加速后再继续;docker compose pull 同样遵循该代理配置。
四、部署步骤
4.1 环境变量文件
在编排目录创建 .env(本文示例密码统一 q1w2e3r4,生产请替换):
DB_PASSWORD=q1w2e3r4
CUSTOM_IMAGE=ghcr.io/frappe/helpdesk
CUSTOM_TAG=stable
PULL_POLICY=missing
键位说明见第六章。CUSTOM_IMAGE/CUSTOM_TAG 是把官方编排中的默认应用镜像(frappe/erpnext)替换为 Helpdesk 官方镜像的关键。
4.2 端口发布 override
⚠️ 实测重要:现行 frappe_docker 的 compose.yaml 不再默认发布 8080 端口(面向反代前置的部署形态)。直连测试需要自建一个小 override,新建 compose.ports.yml:
services:
frontend:
ports:
- "8080:8080"
4.3 项目名与启动命令
⚠️ 实测坑:Compose 项目名不允许包含点号,frappe-helpdesk-1.31.0-stack 会被直接拒绝:
invalid project name "frappe-helpdesk-1.31.0-stack": must consist only of lowercase alphanumeric characters, hyphens, and underscores as well as start with a letter or number
本文使用 frappe-helpdesk-1-31-0-stack。把四个 -f 参数固化为 shell 变量后启动(生产建议写成 deploy.sh 或 Makefile 固化):
CF="-f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/compose.redis.yaml -f compose.ports.yml"
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF up -d
实测回显(末段):
Container frappe-helpdesk-1-31-0-stack-queue-short-1 Started
Container frappe-helpdesk-1-31-0-stack-backend-1 Started
Container frappe-helpdesk-1-31-0-stack-queue-long-1 Started
Container frappe-helpdesk-1-31-0-stack-scheduler-1 Started
Container frappe-helpdesk-1-31-0-stack-websocket-1 Started
Container frappe-helpdesk-1-31-0-stack-frontend-1 Started
查看状态(9 个服务 + 1 个一次性初始化任务):
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF ps --format "table {{.Service}}\t{{.Status}}"
实测回显:
SERVICE STATUS
backend Up 21 seconds
db Up 29 seconds (healthy)
frontend Up 20 seconds
queue-long Up 21 seconds
queue-short Up 21 seconds
redis-cache Up 29 seconds
redis-queue Up 29 seconds
scheduler Up 21 seconds
websocket Up 21 seconds
configurator 是一次性服务:首次 up 时向公共站点配置写入 db_host、db_port、redis_cache、redis_queue、redis_socketio、socketio_port、chromium_path 后即退出(Exited 状态属正常,restart: on-failure 只在失败时重跑)。
4.4 创建站点并安装 Helpdesk
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF exec backend \
bench new-site hd.example.com \
--mariadb-root-password q1w2e3r4 \
--admin-password q1w2e3r4 \
--install-app helpdesk
实测回显(末段,进度条略):
Installing frappe...
Updating DocTypes for frappe : [========================================] 100%
Updating Dashboard for helpdesk
[]
*** Scheduler is disabled ***
站点创建即完成 helpdesk 应用安装(镜像内自带)。开启调度器:
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF exec backend \
bench --site hd.example.com enable-scheduler
# Enabled for hd.example.com
⚠️ 关键加固步骤(不做出栈重启后会挂,见 11.3):把站点数据库用户的 host 从「创建时的 backend 服务 IP」规范化为任意主机:
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF exec db mariadb \
-uroot -pq1w2e3r4 \
-e "RENAME USER '_54c76d77917ea10b'@'172.18.0.6' TO '_54c76d77917ea10b'@'%';"
其中数据库名/用户名取自 site_config.json(docker compose ... exec backend cat sites/hd.example.com/site_config.json 实测回显):
{
"db_name": "_54c76d77917ea10b",
"db_password": "jlkoUKNIvH4jwlsI",
"db_type": "mariadb"
}
host 原值以 SELECT User,Host FROM mysql.user WHERE User='<db_name>'; 实查为准(本文实测为 172.18.0.6)。
4.5 验证
wget -qO- --header "Host: hd.example.com" http://localhost:8080/api/method/ping
# {"message":"pong"}
wget -S -qO /dev/null --header "Host: hd.example.com" http://localhost:8080/helpdesk 2>&1 | head -1
# HTTP/1.1 200 OK
多站点按 Host 头路由:直接访问 http://<服务器IP>:8080 不带正确 Host 会拿不到目标站点,浏览器验证请把 hd.example.com 解析到服务器 IP(或本机测试写入 hosts)。坐席端地址 http://hd.example.com:8080/helpdesk,账号 Administrator,密码为 4.4 节 --admin-password 设置值。
创建一张工单做数据验证(后端内直接调用 API 层):
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF exec backend \
bench --site hd.example.com execute frappe.client.insert \
--kwargs '{"doc": {"doctype": "HD Ticket", "subject": "B2 持久化验证工单"}}'
实测回显(节选——可见 SLA 引擎已自动生效):
{"name": "0002", "owner": "Administrator", "subject": "B2 持久化验证工单", "status": "Open", "priority": "Medium", "sla": "Standard", "response_by": "2026-10-26 12:05:39.745169", "agreement_status": "First Response Due", "doctype": "HD Ticket"}
五、持久化说明
5.1 数据卷布局
官方编排使用三个命名卷(docker volume ls 实测回显):
frappe-helpdesk-1-31-0-stack_db-data
frappe-helpdesk-1-31-0-stack_redis-queue-data
frappe-helpdesk-1-31-0-stack_sites
| 卷 | 内容 | 挂载点 |
|---|---|---|
sites | 全部站点目录(含 site_config、上传文件、备份) | backend / frontend / websocket 共享 /home/frappe/frappe-bench/sites |
db-data | MariaDB 数据目录 | db /var/lib/mysql |
redis-queue-data | 队列 Redis 持久化 | redis-queue /data |
需要把数据直接落在宿主机目录时,官方提供现成 override:追加 -f overrides/compose.bind-mount-db-data.yaml(数据库)或 -f overrides/compose.bind-mount-sites.yaml(站点目录),并按其说明设置宿主路径。
5.2 重启持久化实测
创建工单(4.5 节,count=2)后做完整启停循环:
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF down
docker volume ls --format "{{.Name}}" | grep frappe
# frappe-helpdesk-1-31-0-stack_db-data
# frappe-helpdesk-1-31-0-stack_redis-queue-data
# frappe-helpdesk-1-31-0-stack_sites
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF up -d
重启后复查(实测回显):
2 ← HD Ticket 数量,数据完好
{"message":"pong"}
down 不带 -v 时三个卷全部保留;down -v 会连卷一起删除,等于清库,只应在按第十章恢复演练时使用。
六、环境变量表
以下默认值全部取自 frappe_docker compose.yaml 与 overrides 实查原文:
| 变量 | 默认值 | 说明 |
|---|---|---|
DB_PASSWORD | 123 | MariaDB root 密码(db 服务的 MYSQL_ROOT_PASSWORD) |
CUSTOM_IMAGE | frappe/erpnext | 应用镜像仓库,Helpdesk 部署必须改为 ghcr.io/frappe/helpdesk |
CUSTOM_TAG | $ERPNEXT_VERSION | 应用镜像标签,Helpdesk 部署设为 stable 或具体版本 |
PULL_POLICY | always | 镜像拉取策略;离线/本地已有镜像时设 missing |
RESTART_POLICY | unless-stopped | 业务服务重启策略 |
NGINX_LISTEN_PORT | 8080 | frontend(nginx)监听端口 |
FRAPPE_SITE_NAME_HEADER | $$host | 按 Host 头匹配站点;单站点固定域名时可设为站点名 |
UPSTREAM_REAL_IP_ADDRESS | 127.0.0.1 | 真实客户端 IP 的反代来源 |
UPSTREAM_REAL_IP_HEADER | X-Forwarded-For | 真实 IP 传递头 |
UPSTREAM_REAL_IP_RECURSIVE | off | 递归解析真实 IP |
PROXY_READ_TIMEOUT | 120 | nginx 上游读超时(秒) |
CLIENT_MAX_BODY_SIZE | 50m | 上传体积上限 |
GUNICORN_WORKERS | 2 | backend gunicorn 进程数 |
GUNICORN_THREADS | 4 | backend gunicorn 线程数 |
GUNICORN_TIMEOUT | 120 | gunicorn 请求超时(秒) |
DB_HOST / DB_PORT | 由 mariadb override 注入 db / 3306 | configurator 写入公共配置 |
REDIS_CACHE / REDIS_QUEUE | 由 redis override 注入 redis-cache:6379 / redis-queue:6379 | 同上 |
SOCKETIO_PORT | 9000(固定) | websocket 服务端口 |
七、配置说明
分层配置模型:
- 编排层:
.env+ 四个-f文件,决定「跑什么镜像、怎么联网、卷怎么挂」; - 公共站点配置:
configurator首次启动写入 sites 卷下common_site_config.json(db_host、redis 地址、socketio_port 等),可用docker compose ... exec backend bench set-config -g <键> <值>修改; - 站点配置:
sites/<站点名>/site_config.json(db_name、db_password、maintenance_mode 等),修改方式与逐键含义见本专栏《Frappe Helpdesk 1.31 配置参数详解》。
站点内配置修改示例(改完无需重启 backend,即时生效):
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF exec backend \
bench --site hd.example.com set-config maintenance_mode 1
八、挂载与数据卷管理
常用运维操作(均已实测):
# 查看卷占用
docker volume ls --format "{{.Name}}" | grep frappe-helpdesk
# 进入 backend 交互终端
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF exec backend bash
# 把备份产物从 backend 拷到编排目录(配合第十章恢复演练)
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF \
cp backend:/home/frappe/frappe-bench/sites/hd.example.com/private/backups/. ./backups/
生产建议:至少把 sites 卷对应的站点目录(含 private/backups)纳入定期备份计划;数据库卷可用快照 + bench --site backup 双通道兜底。
九、与等价 docker run 的关系
Helpdesk 官方发布形态就是多服务编排(backend、frontend、websocket、两个队列 worker、scheduler、db、双 Redis,共 9 个常驻服务 + 1 个一次性 configurator),没有官方单容器镜像。用裸 docker run 等价复现需要手工建网络、逐个起 9 个容器、手工对齐共享卷与依赖顺序,可维护性远低于 compose,因此本文不提供逐步 docker run 形态,直接采用官方 compose 文件(其本身即「docker run 参数的声明式写法」)。理解 compose 内部发生了什么的最小等价视角:up -d = 建网 + 按依赖顺序 run 全部服务;down = stop + rm(卷默认保留)。
十、日常运维命令
CF="-f compose.yaml -f overrides/compose.mariadb.yaml -f overrides/compose.redis.yaml -f compose.ports.yml"
# 状态与日志
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF ps
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF logs -f backend
# 重启单个服务
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF restart scheduler backend
# 数据库备份(含附件)
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF exec backend \
bench --site hd.example.com backup --with-files
备份实测回显:
Backup Summary for hd.example.com at 2026-10-23 12:08:07.718592
Config : ./hd.example.com/private/backups/20261023_120807-hd_example_com-site_config_backup.json 94.0B
Database: ./hd.example.com/private/backups/20261023_120807-hd_example_com-database.sql.gz 270.8KiB
Public : ./hd.example.com/private/backups/20261023_120807-hd_example_com-files.tar 10.0KiB
Private : ./hd.example.com/private/backups/20261023_120807-hd_example_com-private-files.tar 10.0KiB
Backup for Site hd.example.com has been successfully completed with files
备份产物位于 sites 卷 hd.example.com/private/backups/ 下,按第八章 compose cp 拷出留存。
10.1 灾难恢复闭环(实测)
目标场景:三个卷全部丢失后,从备份文件把站点恢复回来。以下为本文实测通过的全流程:
# 1. 彻底清场(卷一并删除,模拟灾难)
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF down -v
# 2. 全新拉起并创建同名空站点(仍需 --install-app helpdesk 提供表结构)
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF up -d
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF exec backend \
bench new-site hd.example.com --mariadb-root-password q1w2e3r4 --admin-password q1w2e3r4 --install-app helpdesk
# 3. 把第十章拷出的备份文件送回 backend
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF cp \
./backups/20261023_121003-hd_example_com-database.sql.gz backend:/tmp/
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF cp \
./backups/20261023_121003-hd_example_com-files.tar backend:/tmp/
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF cp \
./backups/20261023_121003-hd_example_com-private-files.tar backend:/tmp/
# 4. 恢复(显式传 root 密码,避免交互卡住)
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF exec backend \
bench --site hd.example.com restore /tmp/20261023_121003-hd_example_com-database.sql.gz \
--db-root-password q1w2e3r4 \
--with-public-files /tmp/20261023_121003-hd_example_com-files.tar \
--with-private-files /tmp/20261023_121003-hd_example_com-private-files.tar
恢复完成实测回显(MariaDB 11.8 警告属官方已知提示,可忽略):
Warning: MariaDB version ['11.8', '9'] is more than 10.8 which is not yet tested with Frappe Framework.
App frappe already installed
Site hd.example.com has been restored with files
恢复后复核(实测回显):
2 ← 恢复前创建的工单数量
{"message":"pong"}
10.2 版本升级
# 1. 修改 .env 中 CUSTOM_TAG(如 stable → v1.32.0,或保持 stable 重新拉取)
# 2. 拉新镜像并重建业务服务
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF pull
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF up -d
# 3. 数据库迁移(所有站点)
docker compose --project-name frappe-helpdesk-1-31-0-stack $CF exec backend bench --site hd.example.com migrate
升级前务必先执行第十章备份;stable 标签跨大版本时先阅读官方 release notes 中的 breaking change 说明。
十一、常见问题与排障实录
11.1 project name 含点号被拒
现象:invalid project name "frappe-helpdesk-1.31.0-stack": must consist only of lowercase alphanumeric characters, hyphens, and underscores ...。解决:改用连字符命名(本文 frappe-helpdesk-1-31-0-stack)。
11.2 部署完 8080 端口不通
原因:现行 frappe_docker compose.yaml 默认不发布端口(预期前面有反代)。解决:按 4.2 加 compose.ports.yml override 或自建反代。
11.3 重启后全站 500,backend 日志 Access denied for user
实测现象:docker compose down → up 后接口报 pymysql.err.OperationalError: (1045, "Access denied for user '_54c76d77917ea10b'@'172.18.0.8' (using password: YES)"),frontend 返回 500。根因:bench new-site 在 db 服务内创建的站点用户,其 host 字段被钉死为创建时 backend 的容器 IP(实测 172.18.0.6);服务重建后 backend 换了 IP(172.18.0.8),授权记录不再匹配。解决:建站后立即执行 4.4 节的 RENAME USER ...@'%' 规范化;已踩坑时对现存用户执行同样的 RENAME USER 即可,无需重建数据。
11.4 configurator 一直 Exited
属正常:它是一次性初始化任务,成功退出即完成使命。只有反复重启失败时才需要 docker compose logs configurator 排查(常见原因是 db 未 healthy 就被拉起,编排已通过 condition: service_healthy 规避)。
11.5 bench restore 卡在 MySQL root password 交互
原因:restore 需要 root 权限重建数据库,未传参会交互询问,脚本/管道场景直接挂住。解决:加 --db-root-password <密码>(见 10.1)。
11.6 恢复时报 MariaDB version more than 10.8 not yet tested
官方对 MariaDB 11.x 的兼容性提示,实测备份恢复全流程可正常完成(本文 10.1 节即在该警告下通过)。保守派可将 override 中 db 镜像改回 mariadb:10.6 并重建卷。
11.7 wget/curl 测试时 Host 头必须带上
多站点按 Host 路由,--header "Host: hd.example.com" 缺失时命中的不是目标站点(表现为 404 或默认站点)。生产环境靠 DNS 解析自然携带正确 Host。
十二、参考链接
- frappe_docker 官方仓库:https://github.com/frappe/frappe_docker(compose.yaml 与 overrides 目录)
- Helpdesk 官方仓库 README(Production Setup / Self Hosting):https://github.com/frappe/helpdesk
- Helpdesk 官方文档:https://docs.frappe.io/helpdesk
- bench 手工安装全流程:本专栏《Frappe Helpdesk 1.31 Ubuntu 22.04 安装指南(bench 手工部署)》
- 站点配置项逐键详解:本专栏《Frappe Helpdesk 1.31 配置参数详解》
- bench 命令速查:本专栏《Frappe Helpdesk 1.31 常用 CLI 命令与工具详解》
- 产品定位与选型对比:[《Frappe Helpdesk 1.31 介绍与选型指南》](https://www.quzuo.net/document/xtxb3uZrBRAB)