The Long Road to a Working Cyrus JMAP Server in 2026
My journey from Dovecot to Cyrus to get the JMAP experience
PART 1: Why JMAP – What do I need to set it up – Prologue
For a long time I have been wanting to serve my email via JMAP. JMAP supports labels (you will know them from Fastmail and GMail). JMAP treats mailboxes as labels, and so you can stick a bunch of labels on an email. IMAP’s model is: One mail, one folder. And support for anything but the few default tags is not wide-spread, which makes it difficult to mark messages with different tags/labels (and in IMAP that would mean copying the message to as many folders/mailboxes as you have labels/tags).
Now that more and more clients have become available for JMAP (terminal mail clients; webmail; mobile apps; and there are rumours that Thunderbird will support JMAP in the future, too), I thought it was time to explore the landscape of serving JMAP.
Up until recently I used to well-respected Dovecot, and I have been very happy with it! It just lacks JMAP support.
Dovecot seems to be run by one or two people, with support from others, from what I can gather from the mailing list. This is probably one of the reasons why, despite requests for many years, JMAP is understandably not on the horizon for Dovecot.
So, I looked to Cyrus, as it is (probably in a modified way) used by Fastmail. Fastmail devs also heavily contribute to Cyrus, which is a great perk. To my astonishment, the Internet is full of articles on how to migrate from Cyrus to Dovecot, but not the other way around. I also couldn’t find any articles or tutorials on setting up and configuring a JMAP server.
With this series of posts I want to fill that gap. I will describe my experience (somewhat lengthy and painful) of migrating from Dovecot to Cyrus, and to JMAP; and I will also post a tutorial on how to set up a Cyrus JMAP server with Apache reverse proxy on Debian Stable (Trixie at this moment).
The setup was as follows: clone the current mail server, install Cyrus (listening on non-standard ports) alongside Dovecot, get it all running with JMAP, somehow hook up MariaDB (Postfixadmin schema) for auth; then attempt to migrate emails and sieve rules from Dovecot to Cyrus. If that works, production can be migrated. As you can imagine, lots of room for things to go fantastically wrong! Yay.
I hit a couple of walls during this migration attempt, and, for the sake of drama, the following parts of this article will, well, focus on the walls and my progress past them.
Prologue: June, in brief
Some time during June I tried to figure out more concretely what I really wanted. I figured that I wanted the following: JMAP (labels + it’s new and shiny), and a GUI for mailbox administration. With Postfix + Dovecot I had gotten used to using postfixadmin. If you are not a sysadmin at your day job, and you only run a small mail server for yourself, some projects you maintain, and perhaps some family and friends, then you don’t have to do too much mail administration. As a result, there is no muscle memory when it comes to adding a new domain or mailboxes, or quotas, or sieve scripts. This is where GUI’s are not just nice, but kind of required.
Practically speaking, this is how I envisaged the migration to go:
- Clone my primary mail server, which runs on Debian 13
- Add Cyrus alongside Dovecot, so that I could set Cyrus up with JMAP, and make sure it worked
- Then find a way to migrate the emails and sieve scripts from Dovecot (mdbox format) to Cyrus (its own format in its own mailstore database). I made a mental note that the easiest way would probably be to use some kind of IMAP sync programme.
The first step was, then, to install cyrus-imapd on the Debian 13 mail server. Ha! Think again. apt immediately balked and informed me that I already had an imap-server installed (Dovecot) and that I could not install another one. I resorted to running dpkg -i --force-conflicts, which borked any future apt installs or updates, until I marked the cyrus-imapd package as “Hold”.
I put Cyrus on ports 1143 / 1993 / 14190 against Dovecot’s 143 / 993 / 4190.
Then, after some searching, I realised that Postfixadmin does not work with Cyrus (it has a happy ending). So, I looked for other GUI admin tools for Cyrus for the reasons mentioned above. Nothing really came up - catastrophe! I filed this away to figure out later (I still wanted to poke at a JMAP server!). As I said, you will find out that this has a happy ending.
By the end of June I had Cyrus running (alongside Dovecot), and a first login working via its local sasldb – and a great sense of how much I did not know about this whole new stack!
Then July arrived, and with that the actual road to a working JMAP server (Cyrus).