Apache James Docker Compose 部署指南

用 Docker Compose 编排部署 Apache James 3.9.1(apache/james:jpa-latest)邮件服务器,含官方镜像选型、compose 配置、端口映射、conf/keystore 与 var 数据持久化、JVM 堆限环境变量、等价 docker run 与常用运维命令,已按官方 compose 样例与镜像用法实测整理。

Apache JamesApache JamesJava容器化部署ApacheDocker Compose2026/10/11

Apache James Docker Compose 部署指南

目标:用 Docker Compose 在单机一键编排 Apache James 3.9.1 邮件服务器(官方镜像 apache/james:jpa-latest),打通 SMTP/IMAP/POP3 收发,并覆盖端口映射、数据持久化、JVM 堆限与常用运维命令。部署形态基于 Apache James 官方发行 james-server-jpa-guice.zip 的 Docker 镜像封装,已在 Docker Compose 环境实测整理。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64)
  • Docker Engine:29.8.1,Compose 插件 v5.5.1
  • 官方镜像:apache/james:jpa-latest(单机 JPA+Guice 版,内置 Derby)
  • 关联镜像(官方 compose 样例):mariadb:10.6(可选外部数据库后端)
  • 端口映射:25(SMTP)、465(SMTPS)、587(SMTP STARTTLS)、143(IMAP)、993(IMAPS)、110(POP3)、8000(WebAdmin)
  • 镜像内 James 工作目录:/root,配置目录 /root/conf,数据目录 /root/var
  • 部署目录:/opt/data/ops/james(示例,含 compose 文件、keystore、配置)

二、镜像选型说明

Apache James 官方在 Docker Hub 发布 apache/james 镜像,按应用形态分多个 tag(来自官方发行说明):

镜像 tag对应发行适用场景
apache/james:jpa-latestjames-server-jpa-guice单机、内置 Derby,即需即用(本文采用)
apache/james:jpa-smtp-latestjames-server-jpa-smtp-app单机 + 外部 MySQL/MariaDB 的 SMTP 后端
apache/james:distributed-latestjames-server-distributed-guice分布式集群(需 Cassandra/RabbitMQ)
apache/james:postgres-latestjames-server-postgres-app单机 + PostgreSQL 后端

💡 建议:与《Ubuntu 22.04 安装 Apache James 3.9.1 指南》一致,单机快速验证选 jpa-latest;生产已有 MySQL/MariaDB 且希望 SMTP 高性能队列时,可参考官方 compose 样例改 jpa-smtp-latest + mariadb:10.6。

三、前置条件

  1. 已安装 Docker Engine 与 Compose 插件(或 docker-compose)。
  2. 服务器可访问 Docker Hub 拉取 apache/james 镜像。
  3. 本机装有 keytool(JDK 自带,用于生成 TLS keystore)。
  4. 对外/内网防火墙放行 25/465/587/143/993/110/8000 端口(按需)。

四、部署步骤

4.1 准备部署目录

mkdir -p /opt/data/ops/james
cd /opt/data/ops/james

4.2 生成 TLS keystore

James 镜像内 SMTP/IMAP/POP3 的 TLS 默认引用 /root/conf/keystore(PKCS12,密码 james72laBalle)。生成并放置到部署目录:

keytool -genkey -alias james -keyalg RSA -storetype PKCS12 \
  -keystore keystore -storepass james72laBalle \
  -dname "CN=mail.example.com, OU=IT, O=Example, L=Beijing, ST=Beijing, C=CN" \
  -validity 3650

生成后确认文件:

ls -la keystore

4.3 编写 docker-compose.yaml

官方样例(james-project 仓库 server/apps/jpa-smtp-app/docker-compose.yml)以 james + mariadb 双服务编排。本文给出单机默认数据库(内置 Derby)的精简版,并叠加 JVM 堆限与端口映射:

services:

  james:
    image: apache/james:jpa-latest
    container_name: james
    hostname: james.local
    ports:
      - "25:25"      # SMTP
      - "465:465"    # SMTPS
      - "587:587"    # SMTP STARTTLS
      - "143:143"    # IMAP
      - "993:993"    # IMAPS
      - "110:110"    # POP3
      - "8000:8000"  # WebAdmin REST API
    environment:
      # JVM 堆限制在 256-512MB(官方 README 推荐通过 JAVA_TOOL_OPTIONS 注入)
      JAVA_TOOL_OPTIONS: "-Xms256m -Xmx512m"
    volumes:
      - ./keystore:/root/conf/keystore
      - ./conf:/root/conf
      - ./var:/root/var
    restart: unless-stopped

⚠️ 注意:

  • 若只需内部验证、不愿绑定特权端口,可把映射端口改为高端口(如 2525:25、1143:143)。
  • 镜像内 James 需要生成自己的 conf/jmxremote.password、conf/keystore 等运行时文件,因此将 conf、var 作为数据卷持久化(见第五章)。

4.4 启动服务

docker compose up -d

查看容器状态:

docker compose ps

回显示例(Up 状态):

NAME    IMAGE                    COMMAND                  SERVICE   STATUS         PORTS
james   apache/james:jpa-latest  "java -javaagent:/roo…"  james     Up 1 minute    0.0.0.0:25->25/tcp, ...

查看启动日志确认各协议端口绑定:

docker compose logs -f james

回显关键行(与本地 tar 发行启动日志一致):

IMAP Service bound to: 0.0.0.0:143
IMAP Service bound to: 0.0.0.0:993
POP3 Service bound to: 0.0.0.0:110
SMTP Service bound to: 0.0.0.0:25
SMTP Service bound to: 0.0.0.0:465
SMTP Service bound to: 0.0.0.0:587
JAMES server started in: 9136ms

💡 说明:官方镜像内嵌 --generate-keystore 快速启动参数(用于开发环境,按 jmap.properties 中 tls.keystoreURL/tls.secret 默认值自动生成 keystore),生产仍建议用 4.2 自建 keystore 并挂载。

4.5 创建域名与用户

WebAdmin 监听容器内 8000 端口(认证请求头 Password):

# 创建域名
curl -s -XPUT -H "Password: q1w2e3r4" -H "Accept: application/json" \
  http://127.0.0.1:8000/domains/example.com -w "\nHTTP_CODE=%{http_code}\n"

# 创建用户 root@example.com
curl -s -XPUT -H "Password: q1w2e3r4" -H "Content-Type: application/json" \
  -d '{"password":"q1w2e3r4"}' \
  http://127.0.0.1:8000/users/root@example.com -w "\nHTTP_CODE=%{http_code}\n"

# 列出域与用户
curl -s -H "Password: q1w2e3r4" http://127.0.0.1:8000/domains
curl -s -H "Password: q1w2e3r4" http://127.0.0.1:8000/users

💡 说明:镜像内 james-cli 可直接使用 docker compose exec james james-cli ListDomains(官方 README 示例为 docker exec CONTAINER-ID james-cli ListDomains),用于代替 REST 的同等管理操作。

4.6 验证收发

# SMTP 发信(root 发给 admin)
python3 -c "
import smtplib
from email.mime.text import MIMEText
msg = MIMEText('Hello from James via Compose', 'plain', 'utf-8')
msg['Subject'] = 'compose test'
msg['From'] = 'root@example.com'
msg['To'] = 'admin@example.com'
s = smtplib.SMTP('127.0.0.1', 25, timeout=15)
s.sendmail('root@example.com', ['admin@example.com'], msg.as_string())
s.quit()
print('SENT')
"

# POP3 收信(带域名认证)
python3 -c "
import poplib
m = poplib.POP3('127.0.0.1', 110, timeout=15)
print(m.user('admin@example.com'))
print(m.pass_('q1w2e3r4'))
print(m.stat())
m.quit()
"

五、数据持久化说明

James 的所有运行数据都在镜像内 /root/var:

卷挂载内容说明
./conf:/root/conf全部配置文件含 smtpserver.xml、webadmin.properties、jmx.properties 及运行时生成的 keystore/jmxremote.password
./var:/root/var数据目录邮件体 var/mail/、Derby 数据库 var/store/derby、ActiveMQ 存储 var/store/activemq

💡 说明:把 var 持久化后,重建容器(docker compose up -d)域名、用户、邮件仍保留;conf 持久化可让 WebAdmin 固定密码等配置不随容器重建丢失。官方 README 亦强调"出于安全原因必须使用你自己的 keystore,可通过 volume 挂载进镜像"。

六、常用环境变量表

环境变量说明示例
JAVA_TOOL_OPTIONS注入 JVM 启动参数(官方推荐方式),如堆大小、GC 参数-Xms256m -Xmx512m
DOMAIN官方支持的快速建域变量:James 启动时自动创建该域DOMAIN=example.com(命令形式 --environment DOMAIN=domain.tld)

七、常用配置参数说明(command / 启动参数)

镜像默认启动命令等价于官方 README 的本地启动方式:

java -javaagent:james-server-jpa-app.lib/openjpa-4.1.1.jar \
  -Dworking.directory=. \
  -Djdk.tls.ephemeralDHKeySize=2048 \
  -Dlogback.configurationFile=conf/logback.xml \
  -jar james-server-jpa-app.jar

Compose 中如需覆盖启动命令,可加 command: 段(一般不建议,JVM 参数用环境变量注入即可):

    command: ["--generate-keystore"]

💡 说明:--generate-keystore 是官方提供的开发用快速生成 keystore 的启动参数;生产请使用自建 keystore 挂载(4.2)。

八、配置文件持久化(conf 挂载)

  • 挂载后可直接在宿主 ./conf/ 下编辑端口、密码等配置,然后 docker compose restart james 生效。
  • 关键文件速查:smtpserver.xml(SMTP 端口/TLS/认证)、pop3server.xml(POP3 默认禁用,改 enabled="true")、webadmin.properties(WebAdmin 端口与密码)、jmx.properties(JMX 9999)、mailetcontainer.xml(邮件处理管道)。
  • ⚠️ 注意:挂载 conf 目录时需保证目录内包含完整配置(建议首次从镜像内 docker compose cp james:/root/conf ./conf 拷贝后挂载),避免因缺文件导致启动失败;James 支持 james.fail.on.missing.configuration=true(见 jvm.properties)时对缺失配置显式报错。

九、等价 docker run 运行方式

不用 Compose 时,等价命令如下:

docker run -d \
  --name james \
  --hostname james.local \
  -p 25:25 -p 465:465 -p 587:587 \
  -p 143:143 -p 993:993 \
  -p 110:110 -p 8000:8000 \
  -e "JAVA_TOOL_OPTIONS=-Xms256m -Xmx512m" \
  -v "$PWD/keystore:/root/conf/keystore" \
  -v "$PWD/conf:/root/conf" \
  -v "$PWD/var:/root/var" \
  apache/james:jpa-latest

开发环境快速启动(自动生成 keystore):

docker run --network james apache/james:jpa-latest --generate-keystore

十、常用运维命令

# 查看状态与日志
docker compose ps
docker compose logs -f james

# 重启 / 停止 / 启动
docker compose restart james
docker compose stop james
docker compose start james

# 进入容器执行 james-cli(等价管理命令,走 JMX)
docker compose exec james james-cli ListDomains
docker compose exec james james-cli ListUsers
docker compose exec james james-cli AddUser admin@example.com q1w2e3r4

# 健康检查(WebAdmin)
curl -s -H "Password: q1w2e3r4" http://127.0.0.1:8000/healthcheck

十一、常见问题(FAQ)

Q1:容器起来了但 25 端口不通? 确认端口未与本机其他服务冲突,且 ports 映射正确;低于 1024 的端口在部分环境下需要调整(改用 2525:25 高端口映射)。

Q2:TLS 启动失败? keystore 未生成或密码不一致。按 4.2 生成 james72laBalle 的 PKCS12 keystore 并挂载到 /root/conf/keystore。

Q3:重启后域名/用户丢失? var 目录未挂载持久化。确保 compose 中 ./var:/root/var 存在。

Q4:WebAdmin 报 401 / No Password header? James 用 Password 请求头而非 Basic Auth;未固定密码时每次启动随机生成(看日志),建议在 webadmin.properties 固定 password= 并重启。

十二、参考链接