Cyrus IMAP 3.4 Docker Compose 部署指南
无官方镜像场景下用 Ubuntu 22.04 基础镜像自建 Cyrus IMAP 3.4 镜像的 Compose 部署:Dockerfile/entrypoint/双配置文件/数据卷持久化全实测。
Cyrus IMAP 3.4 Docker Compose 部署指南
目标:用 Docker Compose 一键拉起一套可登录、数据可持久化的 Cyrus IMAP 3.4 服务(IMAP 143 + ManageSieve 4190)。Cyrus 官方未发布 Docker 镜像,本文采用「Ubuntu 22.04 基础镜像内装官方仓库 deb」的自建镜像形态,全文已在 Docker 27 环境实测通过。
一、环境信息
- Docker 27+ / Docker Compose v2
- 基础镜像:
ubuntu:22.04(官方仓库提供 cyrus-imapd 3.4.3-3ubuntu0.3) - 自建镜像:
cyrus-imapd:3.4.3-ubuntu22.04(Dockerfile 现场构建) - Compose 项目名:
cyrus-3.4-stack,容器名cyrus-3.4-compose - 宿主端口映射:8128→143(IMAP)、8129→4190(ManageSieve)
- 数据卷:
cyrus-data(/var/lib/cyrus)、cyrus-spool(/var/spool/cyrus)、cyrus-sieve(/var/spool/sieve) - 演示账号:
cyrus/q1w2e3r4(首次启动自动初始化,仅演示环境)
二、镜像选型说明
2026-10-25 实查 Docker Hub:Cyrus 官方(cyrusimap 组织)未发布官方镜像,搜索结果仅有 threez/cyrus-imap、linagora/cyrus-imap 等社区镜像,更新频率与供应链可信度参差不齐。
| 方案 | 说明 | 取舍 |
|---|---|---|
| 社区镜像(threez/cyrus-imap 等) | 开箱即用 | 非官方维护、版本滞后、构建不透明,不推荐生产 |
| 自建镜像:Ubuntu 基础镜像 + 官方 deb(本文) | 版本与发行版仓库一致、构建过程全透明 | 需维护一个 30 行 Dockerfile,推荐 |
💡 技术拓展:邮件类服务的容器镜像形态主要有三种——
形态 代表 特点 官方镜像 poste.io、mailu 各组件 供应链可信、升级节奏跟官方 社区镜像 docker-mailserver、threez/cyrus-imap 全家桶整合好,但依赖维护者活跃度 自建镜像(基础镜像+包管理器) 本文方案 最透明可控,代价是自己写 Dockerfile Cyrus 无官方镜像且社区镜像版本老旧,本文采用自建镜像形态。
三、前置条件
- 已安装 Docker 与 Compose 插件(
docker compose version能输出版本); - 宿主 8128/8129 端口空闲(
ss -ltn确认无占用); - 项目目录结构如下(四个文件 + 一个 compose 描述文件):
cyrus-compose/
├── Dockerfile
├── entrypoint.sh
├── imapd.conf
├── cyrus.conf
└── compose.yaml
四、部署步骤
4.1 编写 Dockerfile
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
cyrus-imapd cyrus-admin cyrus-clients sasl2-bin \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
COPY imapd.conf /etc/imapd.conf
COPY cyrus.conf /etc/cyrus.conf
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
EXPOSE 143 993 4190
ENTRYPOINT ["/entrypoint.sh"]
镜像内只装四个包:服务本体、管理工具、测试客户端、SASL 工具,与裸机安装篇的包清单一致。
4.2 编写入口脚本 entrypoint.sh
#!/bin/bash
set -e
# 初始化 Cyrus 运行目录(数据卷首次挂载时)
mkdir -p /var/lib/cyrus /var/spool/cyrus/mail /var/spool/sieve /run/cyrus
chown -R cyrus:mail /var/lib/cyrus /var/spool/cyrus /var/spool/sieve /run/cyrus
# 首次启动初始化管理账号(cyrus / q1w2e3r4,仅演示环境)
# sasldb 落在数据卷内(imapd.conf 中 sasl_sasldb_path 指定)
if [ ! -s /var/lib/cyrus/sasldb2 ]; then
echo "${CYRUS_ADMIN_PASSWORD:-q1w2e3r4}" | saslpasswd2 -p -f /var/lib/cyrus/sasldb2 -c "${CYRUS_ADMIN_USER:-cyrus}"
chown cyrus:mail /var/lib/cyrus/sasldb2
fi
# 前台运行 master 进程
exec /usr/lib/cyrus/bin/master -D
要点:master -D 以前台方式运行(容器 PID 1 语义);sasldb 通过 saslpasswd2 -f 指定落到数据卷,保证容器重建后账号不丢。
4.3 编写 imapd.conf(容器版最小配置)
# Cyrus IMAP 最小可用配置(容器部署形态)
admins: cyrus
configdirectory: /var/lib/cyrus
proc_path: /run/cyrus/proc
mboxname_lockpath: /run/cyrus/lock
defaultpartition: default
partition-default: /var/spool/cyrus/mail
altnamespace: no
unixhierarchysep: no
lmtp_downcase_rcpt: yes
allowanonymouslogin: no
allowplaintext: yes
popminpoll: 1
autocreate_quota: 0
umask: 077
sieveusehomedir: false
sievedir: /var/spool/sieve
hashimapspool: true
sasl_pwcheck_method: auxprop
sasl_sasldb_path: /var/lib/cyrus/sasldb2
sasl_auto_transition: no
lmtpsocket: /run/cyrus/socket/lmtp
idlesocket: /run/cyrus/socket/idle
notifysocket: /run/cyrus/socket/notify
syslog_prefix: cyrus
相比发行版默认配置的三处关键改动:补 admins: cyrus(deb 非交互安装默认不写)、sasl_sasldb_path 把账号库移入数据卷、其余保持默认。
4.4 编写 cyrus.conf(容器版裁剪)
START {
recover cmd="/usr/sbin/cyrus ctl_cyrusdb -r"
delprune cmd="/usr/sbin/cyrus expire -E 3"
tlsprune cmd="/usr/sbin/cyrus tls_prune"
}
SERVICES {
imap cmd="imapd -U 30" listen="imap" prefork=0 maxchild=100
lmtpunix cmd="lmtpd" listen="/run/cyrus/socket/lmtp" prefork=0 maxchild=20
sieve cmd="timsieved" listen="sieve" prefork=0 maxchild=100
notify cmd="notifyd" listen="/run/cyrus/socket/notify" proto="udp" prefork=1
}
EVENTS {
checkpoint cmd="/usr/sbin/cyrus ctl_cyrusdb -c" period=30
delprune cmd="/usr/sbin/cyrus expire -E 3" at=0401
tlsprune cmd="/usr/sbin/cyrus tls_prune" at=0401
deleteprune cmd="/usr/sbin/cyrus expire -E 4 -D 28" at=0430
expungeprune cmd="/usr/sbin/cyrus expire -E 4 -X 28" at=0445
}
默认 cyrus.conf 中 pop3/nntp/http 条目已整体移除(对应 deb 未安装,留着会导致 master 退出,与裸机篇排障同一根因);sieve 监听从 localhost:sieve 改为 sieve(0.0.0.0:4190),便于宿主映射访问。
4.5 编写 compose.yaml 并启动
name: cyrus-3.4-stack
services:
cyrus-imapd:
build: .
image: cyrus-imapd:3.4.3-ubuntu22.04
container_name: cyrus-3.4-compose
hostname: mail.example.com
restart: unless-stopped
ports:
- "8128:143" # IMAP
- "8129:4190" # ManageSieve
environment:
CYRUS_ADMIN_USER: cyrus
CYRUS_ADMIN_PASSWORD: q1w2e3r4
volumes:
- cyrus-data:/var/lib/cyrus
- cyrus-spool:/var/spool/cyrus
- cyrus-sieve:/var/spool/sieve
volumes:
cyrus-data:
cyrus-spool:
cyrus-sieve:
构建并启动:
docker compose build
docker compose up -d
docker compose ps
实测回显:
NAME IMAGE COMMAND SERVICE STATUS PORTS
cyrus-3.4-compose cyrus-imapd:3.4.3-ubuntu22.04 "/entrypoint.sh" cyrus-imapd Up 5 seconds 993/tcp, 0.0.0.0:8128->143/tcp, 0.0.0.0:8129->4190/tcp
4.6 验证登录
进容器用自带测试客户端验证:
docker exec cyrus-3.4-compose /usr/lib/cyrus/bin/imtest -m login -u cyrus -a cyrus -w q1w2e3r4 localhost
S: * OK [CAPABILITY IMAP4rev1 LITERAL+ ID ENABLE AUTH=SCRAM-SHA-1 AUTH=SCRAM-SHA-256 AUTH=DIGEST-MD5 AUTH=NTLM AUTH=CRAM-MD5 AUTH=LOGIN AUTH=PLAIN SASL-IR] mail.example.com Cyrus IMAP 3.4.3-dirty-Debian-3.4.3-3ubuntu0.3 server ready
S: L01 OK [CAPABILITY ...] User logged in SESSIONID=<cyrus-1792902255-33-1-6967620831499250011>
(CAPABILITY 列表较长,已省略中段。)
User logged in 即部署成功;宿主侧邮件客户端直接连 宿主机IP:8128、账号 cyrus、密码 q1w2e3r4 即可。
五、数据持久化说明
| 卷 | 容器内路径 | 内容 |
|---|---|---|
| cyrus-data | /var/lib/cyrus | 邮箱元数据库(mailboxes.db、配额、订阅、sasldb2 账号库) |
| cyrus-spool | /var/spool/cyrus | 邮件正文与索引(partition-default) |
| cyrus-sieve | /var/spool/sieve | 用户 Sieve 过滤脚本 |
持久化有效性实测:docker compose down && docker compose up -d 后,/var/lib/cyrus/sasldb2 仍在且登录照常:
-rw-r----- 1 cyrus mail 12288 Oct 25 04:23 /var/lib/cyrus/sasldb2
六、环境变量表
| 变量 | 默认值 | 说明 |
|---|---|---|
| CYRUS_ADMIN_USER | cyrus | 首次启动创建的管理账号名 |
| CYRUS_ADMIN_PASSWORD | q1w2e3r4 | 上述账号密码(仅首次初始化时生效,演示口令,生产必改) |
⚠️ 注意:账号只在 sasldb2 不存在时创建一次;之后改环境变量不会改已有账号密码,改密码用
docker exec进容器执行echo '新密码' | saslpasswd2 -p -f /var/lib/cyrus/sasldb2 cyrus。
七、配置文件挂载
本文采用「构建期 COPY 进镜像」的方式固化配置,适合配置稳定的场景。若需不改镜像就调整参数,可改用挂载覆盖:
volumes:
- ./imapd.conf:/etc/imapd.conf:ro
- ./cyrus.conf:/etc/cyrus.conf:ro
改完执行 docker compose restart 生效(imapd.conf/cyrus.conf 均非热加载)。
八、等价 docker run
不使用 Compose 时的等价命令(构建镜像后):
docker build -t cyrus-imapd:3.4.3-ubuntu22.04 .
docker run -d --name cyrus-3.4-compose --hostname mail.example.com \
--restart unless-stopped \
-p 8128:143 -p 8129:4190 \
-e CYRUS_ADMIN_USER=cyrus -e CYRUS_ADMIN_PASSWORD=q1w2e3r4 \
-v cyrus-data:/var/lib/cyrus -v cyrus-spool:/var/spool/cyrus -v cyrus-sieve:/var/spool/sieve \
cyrus-imapd:3.4.3-ubuntu22.04
九、常用运维命令
docker compose ps # 查看栈状态
docker compose logs -f # 跟踪 master/imapd 日志
docker compose restart # 改配置后重启
docker compose down # 停止并删除容器(数据卷保留)
docker exec -it cyrus-3.4-compose bash # 进容器排障
docker exec cyrus-3.4-compose cyradm --user cyrus localhost # 打开邮箱管理 Shell(交互输入密码)
邮箱创建、配额、ACL、reconstruct 等完整管理命令实测见《Cyrus IMAP 3.4 常用 CLI 命令详解》。
十、常见问题(FAQ)
Q1:容器启动后立刻退出?
看 docker compose logs:若报 cannot find executable for service 'pop3',说明 cyrus.conf 中残留了未安装包对应的服务条目,按 4.4 的裁剪版覆盖即可;若报 multiple entries for service 'imaps',说明同名服务被放开了两行。
Q2:为什么不用社区镜像 threez/cyrus-imap? 该镜像长期未更新且非官方维护,版本与补丁状态不可控;自建镜像 30 行 Dockerfile 换来的透明度值得(见镜像选型说明)。
Q3:如何启用 993 IMAPS?
生成证书放入容器(或挂载),imapd.conf 增加 tls_server_cert/tls_server_key,cyrus.conf 的 SERVICES 段增加 imaps cmd="imapd -s -U 30" listen="imaps",ports 增加 - "993:993"。完整 TLS/SASL 加固实测见《Cyrus IMAP 3.4 配置参数详解》。
Q4:宿主 8128 连不上?
依次排查:docker compose ps 端口映射是否存在 → 宿主防火墙/安全组是否放行 8128 → docker exec cyrus-3.4-compose ss -ltn(容器内需 iproute2)看 143 是否监听在 0.0.0.0。
十一、参考链接
- Cyrus IMAP 官方文档:https://www.cyrusimap.org/
- cyrus-imapd (Ubuntu jammy) 包页:https://packages.ubuntu.com/jammy/cyrus-imapd
- Docker Compose 官方文档:https://docs.docker.com/compose/
- 专栏导览:《Cyrus IMAP 3 介绍与选型指南》、《Ubuntu 22.04 安装 Cyrus IMAP 3.4 指南》