
Zammad 是什么?
Zammad 是一款开源的企业级客服工单与客户支持系统,旨在帮助团队统一管理全渠道的客户咨询、投诉和内部支持请求,实现标准化、高效化的客户服务流程。它可以替代传统的分散式客服沟通方式(如单独用邮件、微信、电话处理咨询),将所有请求汇聚到一个平台进行跟踪和解决。
项目成功部署后的文件目录
部署完成后,项目的目录结构清晰明了,便于管理和维护。
[student@rocky zammad-docker-compose]$ tree
.
├── caddy
│ ├── conf
│ │ └── Caddyfile
│ ├── data
│ │ └── caddy [error opening dir]
│ ├── docker-compose.yml
│ └── logs
│ ├── access.log
│ └── zammad-access.log
├── docker-compose.yml
├── LICENSE
├── rancher-compose.yml
├── README.md
└── scenarios
├── add-cloudflare-tunnel.yml
├── add-external-network-to-elasticsearch.yml
├── add-external-network-to-nginx.yml
├── add-hostport-to-elasticsearch.yml
├── add-nginx-proxy-manager.yml
├── add-ollama.yml
├── apply-resource-limits.yml
├── disable-backup-service.yml
└── disable-elasticsearch-service.yml
6 directories, 17 files
[student@rocky zammad-docker-compose]$
用 Docker Compose 部署 Zammad
部署过程非常简单,得益于官方提供的 Docker Compose 配置,我们可以快速拉起整个 Zammad 服务栈。
git clone https://github.com/zammad/zammad-docker-compose.git
cd zammad-docker-compose
ls
docker compose up -d
curl -vvv -k http://127.0.0.1:8080/
部署成功后可以通过浏览器访问初始的 HTTP 服务,地址通常是 http://127.0.0.1:8080/ 或你服务器的 IP。
用 Docker Compose 部署 Caddy
为了提供更安全的 HTTPS 访问和反向代理功能,我们引入 Caddy。这里的关键原则是:Caddy 仅作为反向代理和 HTTPS 终结层,将请求转发给 Zammad 内部的 Nginx 服务,不干预 Zammad 应用栈自身的逻辑。
mkdir -p ./caddy/{conf,data,logs}
ls -l caddy/
chmod 755 ./caddy/{conf,data,logs}
cd caddy/conf/
ip addr # 查看服务器IP,用于配置
Caddyfile 的内容
核心配置思路是让 Caddy 专注做好三件事:HTTPS 终结、请求转发和安全强化。所有应用层逻辑(如静态文件服务、WebSocket、业务处理)都交给 zammad-nginx 容器。
cat > Caddyfile <<EOF
# 全局配置:解决监听歧义、SSL SNI问题,优化协议支持
{
# 替换为你的服务器真实内网IP(必改!)
default_sni 192.168.0.109
servers :443 {
# 支持HTTP/1.1、HTTP/2、HTTP/3,适配现代浏览器
protocols h1 h2 h3
}
}
# HTTPS核心:仅做HTTPS终结 + 纯反向代理(所有请求转发给zammad-nginx)
192.168.0.109:443 {
# 1. 离线自签名证书(Caddy核心职责:HTTPS终结)
tls internal
# 2. 安全头强化(提升HTTPS安全性,不影响zammad-nginx)
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains" # 强制HTTPS
X-Content-Type-Options "nosniff" # 防止MIME嗅探
X-Frame-Options "SAMEORIGIN" # 防止点击劫持
X-XSS-Protection "1; mode=block" # 防XSS
Referrer-Policy "strict-origin-when-cross-origin" # 合规的Referrer策略
-Server # 隐藏Caddy服务器标识
}
# 3. 请求体大小限制(适配Zammad工单/附件上传,拦截超大请求)
request_body {
max_size 10GB
}
# 4. 压缩优化(Caddy侧压缩,减轻zammad-nginx压力)
encode gzip
# 5. 核心:纯反向代理所有请求到zammad-nginx(容器内实际监听8080端口)
reverse_proxy zammad-nginx:8080 {
# 5.1 WebSocket配置(Zammad实时通知/聊天必需,长连接优化)
transport http {
keepalive 3600s # 长连接保持1小时
dial_timeout 10s # 连接zammad-nginx超时时间
read_timeout 300s # 后端响应超时(5分钟,适配工单处理)
write_timeout 300s # 后端写入超时
}
# 5.2 转发核心头信息(让zammad-nginx识别真实客户端)
header_up X-Forwarded-Proto {scheme} # 告知后端使用HTTPS协议
header_up X-Forwarded-For {remote} # 传递客户端真实IP
header_up X-Real-IP {remote} # 传递客户端真实IP
header_up Host {host} # 传递客户端访问的主机名/IP
}
# 6. 日志配置(便于排查问题,结构化JSON格式)
log {
level INFO
output file /var/log/caddy/zammad-access.log {
roll_size 100MB # 日志文件达到100MB自动轮转
roll_keep 5 # 保留最近5个轮转文件
}
format json # 便于日志分析工具解析
}
}
# HTTP强制重定向到HTTPS(避免混合协议访问,提升安全性)
http://192.168.0.109 {
redir https://{host}{uri} 301 # 301永久重定向,符合SEO/浏览器缓存规则
}
EOF
Caddy 的 docker-compose.yml 的内容
此配置将 Caddy 容器连接到 Zammad 已创建的 Docker 网络,并映射必要的端口和卷。
cd ..
pwd
cat > docker-compose.yml <<EOF
version: '3.8'
services:
caddy:
image: caddy:2.10.0-alpine
container_name: zammad-caddy-proxy
restart: always
ports:
- "80:80" # HTTP端口,用于重定向到HTTPS
- "18443:443" # HTTPS端口,对外提供Zammad访问
volumes:
- /home/student/zammad-docker-compose/caddy/conf/Caddyfile:/etc/caddy/Caddyfile:ro # 挂载配置文件
- /home/student/zammad-docker-compose/caddy/data:/data # 存放Caddy生成的证书
- /home/student/zammad-docker-compose/caddy/logs:/var/log/caddy # 挂载日志目录
networks: # 使用host网络,确保Caddy能访问宿主机127.0.0.1:8080 或者
- zammad-docker-compose_default
# 若不想用host网络,需确保Caddy容器和Zammad容器在同一Docker网络,此时反向代理地址改为Zammad容器IP:8080
# 声明使用外部网络(Zammad已创建的网络)
networks:
zammad-docker-compose_default:
external: true # 表示该网络已存在,无需Caddy创建
EOF
启动 Caddy 服务
配置完成后,启动 Caddy 容器。现在,你就可以通过 https://你的服务器IP:18443 安全地访问 Zammad 这个功能强大的 客户支持系统 了。
docker compose up -d
docker compose ps
curl -vvv -k https://192.168.0.109:18443
至此,一个基于容器化、具备 HTTPS 安全访问能力的 Zammad 开源工单系统就部署完成了。这种将反向代理(Caddy)与应用核心(Zammad)分离的架构,职责清晰,便于后续维护和扩展。
