The Apache Software Foundation

Setting up an IMAP server

This document will present how to set up a James server in order to serve as a personal IMAP + SMTP server. We will cover:

  • DNS creation and MX record
  • Server components description
  • Generation of a custom keystore
  • Starting James
  • Basic James administration
  • Additional features one might want to enable...

This guide rely on the JPA Guice Docker image. To run it, one need to have docker installed.

DNS resolution

Someone willing to send you an email will first have to discover which IP your mail server has. The way this is achieved is through MX (means Mail eXchange) DNS record.

Imagine sends a mail to Bob will:

  1. Ask DNS server its MX entries
  2. respond that it is
  3. Bob resolves ip address...
  4. ...and can establish a connection to to send an email to Alice

All is needed is a MX entry in domain name resolution pointing to the future IP of your James server.

JAMES architecture

JPA guice docker image relies on an embedded Derby database for storing data. Note that Apache Lucene library is used for email search. A mail queue is implemented on top of an embedded Apache ActiveMQ. Hence James do not need any external service for being running.

JPA guice offers the following protocols:

  • SMTP For receiving emails
  • IMAP For reading emails
  • WebAdmin is a REST API allowing you to manage Apache JAMES

The following protocols are also available:

  • LMTP local version of SMTP
  • POP3 For reading emails. Lacks tests
  • JMX is used by a command line for administrating Apache James
  • And more...

Generation of a custom keystore

In order to maintain a good level of privacy and security, James is relying on TLS cryptography for securing exchanges. We thus need to generate our own personal keystore. Note that this guide do not cover generating a keystore from SSL certificates. A security exception might be configured on the Mail User Agent.

In order to create a keystore, please run: keytool -genkey -alias james -keyalg RSA -keystore /path/to/james/conf/keystore. James is configured with a default password james72laBalle (used to read the keystore). However, we will be overriding the configuration of the docker image, so you can be defining your own.

Starting james

We want to override the configuration of the docker image with a volume.

First let's retrieve a valid configuration:

$ git clone
$ cp -rf james-project/dockerfiles/run/guice/jpa/destination/conf conf
$ mv keystore conf/keystore

Modify all protocol configuration files to match your keystore password (imapserver.xml, lmtpserver.xml, managesieveserver.xml, pop3server.xml, smtpserver.xml).

We will create a local folder for holding data out of the container:

mkdir var

Then, let's start James:

docker run \
--name james_run \
-p "25:25" -p "465:465" -p "587:587" \
-p "143:143"  -p "993:993" \
--volume "$PWD/conf:/root/conf/" \
--volume "$PWD/var:/root/var/" \

Administrating James

We now have a running James server. We just need to tell him which users and domains it should be handling mails for. We will, in order to do this, use the command line:

docker exec james_run java -jar /root/james-cli.jar AddDomain domain.tld
docker exec james_run java -jar /root/james-cli.jar AddUser user@domain.tld secretPassword

The command line client can be used for several other purposes like managing quota, setting addresses redirections, etc.

Additional features

James is a large project with many features. You can go further and complete your installation with an AntiSpam system, or set up metric display, collect logs in ElasticSearch for a display in Kibana, and much more!

Also, James offers support for SPF and DKIM standard, which increase the trust external people can get in your mail system.