Cyrus IMAP 3.4 Docker Compose 部署指南

无官方镜像场景下用 Ubuntu 22.04 基础镜像自建 Cyrus IMAP 3.4 镜像的 Compose 部署:Dockerfile/entrypoint/双配置文件/数据卷持久化全实测。

Cyrus IMAPCyrus IMAP邮件服务器Docker Compose2026/10/25

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_USERcyrus首次启动创建的管理账号名
CYRUS_ADMIN_PASSWORDq1w2e3r4上述账号密码(仅首次初始化时生效,演示口令,生产必改)

⚠️ 注意:账号只在 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。

十一、参考链接