My email setup with Aerc and Git

Motivation

Ever since GMail in the early 2000s1 I have been interacting with emails through the browser, in a webmail. It may sound stupid, but I only recently realised that I was missing out on some pretty cool features of email, such as:

  • Offline access: Webmails require to be online. Not only is it convenient to read/write emails offline, but it is also faster because there is no need to re-download the emails every time.
  • No lock-in: Without owning the domain, it is hard to change provider because it means changing the address and updating it everywhere. Email makes it easy to own the domain, separating the address from the provider.
  • Easy backup: Now that I fetch my emails and keep them offline, I have a mail/ folder that I can easily backup.
  • The right UI for the job: On my phone, I want an graphical app that saves my recent emails so that I can access my cinema ticket offline. On my desktop, I want to backup all my emails, and I want an easy way to forward patches from a mailing list into git (I like TUIs like Aerc or Mutt). Sometimes I want to access my emails from a device I don’t own, and the webmail is convenient for that.

I therefore spent some time setting up an email environment that works well for me. Everyone is different, so what is ergonomic for me may not be for others. But it doesn’t hurt to share my setup and - who knows - it may help someone, someday. You will also find other resources describing similar setups below.

My setup

I am using the following programs:

  • Aerc as my TUI email client (there are others like Mutt). It integrates well with the git email workflow.
  • Git with the email workflow, sending patches with git send-email.
  • isync/mbsync2 to synchronize my mailbox (it downloads my emails into a mail/ folder that Aerc accesses).
  • OpenSMTPD as my SMTP relay, which queues the emails I send while I am offline and sends them later. An alternative would have been msmtp (which is “just” an SMTP client and may therefore be more lightweight) together with the msmtpq script (this setup is described here).

Also note that I am currently using Fastmail as a provider (different providers may require slightly different configurations). I know that JMAP is a thing, but I haven’t found an alternative to isync/mbsync for JMAP yet.

Aerc

Aerc can be used “standalone” (without isync/mbsync and OpenSMTPD), with a simple config like this:

# ./config/aerc/accounts.conf

[Fastmail]
source   = imaps://my-user%40my-domain.com:my-password@imap.fastmail.com:993
outgoing = smtp://my-user%40my-domain.com:my-password@smtp.fastmail.com:587
from     = My User <my-user@my-domain.com>

Where:

  • my-user@my-domain.com is my address and Fastmail username.
  • my-password is the token I got from Fastmail.

But in this setup, Aerc will only work online: you will not have access to the emails when offline, and you will not be able to send emails either.

That is why we will configure isync/mbsync to fetch and store the emails on disk (here in ~/mail/), such that Aerc can access them. We can therefore update the source in Aerc:

source   = maildir://~/mail

In order to send emails while we are offline, we will send them with OpenSMTPD which will queue them and retry sending them when we are back online. We make Aerc leverage this by setting the outgoing param to OpenSMTPD’s sendmail executable:

outgoing = /usr/sbin/sendmail

The final ./config/aerc/accounts.conf looks like this:

# ./config/aerc/accounts.conf

[Fastmail]
source   = maildir://~/mail
outgoing = /usr/sbin/sendmail
default  = INBOX
from     = My User <my-user@my-domain.com>
copy-to  = Sent
check-mail-cmd = 'mbsync -c ~/.config/isync/mbsync.conf primary'
check-mail = 1m
  • source: the mail folder (synchronized with Fastmail by isync/mbsync).
  • outgoing: the sendmail executable that passes the email to OpenSMTPD.
  • check-mail-cmd: the command run by Aerc to check for new emails. Note that it will only be called while Aerc is running. If you want to fetch emails regularly independently from Aerc, consider running the mbsync command in a cron job.
  • check-mail: we tell Aerc to run check-mail-cmd every minute.

Git

Just like for Aerc, we can configure Git to send emails without OpenSMTPD (see this guide for more details):

# ~/.gitconfig

[user]
	email = my-user@my-domain.com
	name = My User
[sendemail]
	smtpserver = smtp.fastmail.com
	smtpuser = my-user@my-domain.com
	smtpencryption = ssl
	smtpserverport = 465
	smtppass = my-password

But again, sending emails will only work online. The good news is that with OpenSMTPD configured, we can just drop the whole [sendemail] section and the emails will be handled by it:

# ~/.gitconfig

[user]
	email = my-user@my-domain.com
	name = My User

Now git send-email will work offline, too, with the outgoing emails being queued in OpenSMTPD.

isync/mbsync

We have configured Aerc to fetch emails from ~/mail/ above, now we need isync/mbsync to actually put them there. Here is my ~/.config/isync/mbsync.conf:

# ~/.config/isync/mbsync.conf

CopyArrivalDate yes
Create Near
Expunge Both

IMAPAccount fastmail
Host imap.fastmail.com
User my-user@my-domain.com
Pass my-password
SSLType IMAPS

MaildirStore local
Path ~/mail/
Inbox ~/mail/INBOX
SubFolders Verbatim

IMAPStore fastmail
Account fastmail

Channel primary
Far :fastmail:
Near :local:
Patterns *

A few notes here:

  • User replaces the smtpuser we had in .gitconfig and the user we had in accounts.conf.
  • Pass replaces the smtppass we had in .gitconfig and the password we had in accounts.conf.
  • I do have issues with Fastmail and CopyArrivalDate yes because isync fails to correctly parse the dates with a 1-digit day (so it fails at the beginning of each month). It turns out that Fastmail (Postfix actually, which is used by Fastmail) is fine and isync is the one parsing incorrectly. There is a fix upstream but it hasn’t made it to a release yet. In my case I compile isync from sources for that reason.

With this configuration, we can synchronize with the Fastmail server by running the following command manually:

mbsync -c ~/.config/isync/mbsync.conf primary

But that’s just for testing, I usually don’t call it directly. Remember: this is the command that Aerc will run every minute as part of the check-mail-cmd mechanism (see the Aerc setup above).

OpenSMTPD

With isync/mbsync, Aerc will fetch and store the emails on the disk for offline use. Now we will setup OpenSMTPD as a relay to send messages, so that they get queued and sent when an Internet connection is available.

Note that OpenSMTPD runs as a service and therefore has to be enabled. Changing the default smtpd.conf to support my use-case was pretty straightforward (it is even described in the “examples” section of the smtpd.conf manpage). First, I created a new /etc/smtpd/secrets file with the following content:

# /etc/smtpd/secrets

me my-user@my-domain.com:my-password

Then I had to add the following two lines to /etc/smtpd/smtpd.conf in order to enable the relay:

# /etc/smtpd/smtpd.conf

table secrets file:/etc/smtpd/secrets

[...]

action "relay" relay host smtp+tls://me@smtp.fastmail.com:587 auth <secrets>

And that was it! The final /etc/smtpd/smtpd.conf file looks like this (I highlighted the two lines I had to add to the default file):

# /etc/smtpd/smtpd.conf

# This is the smtpd server system-wide configuration file.
# See smtpd.conf(5) for more information.

table aliases file:/etc/smtpd/aliases
table secrets file:/etc/smtpd/secrets

# To accept external mail, add something like: listen on eth0
#
listen on lo

action "local" maildir alias <aliases>
action "relay" relay host smtp+tls://me@smtp.fastmail.com:587 auth <secrets>

# Uncomment the following to accept external mail for domain "example.org"
#
# match from any for domain "example.org" action "local"
match for local action "local"
match from local for any action "relay"

Conclusion

We have configured isync/mbsync to synchronise a local folder (~/mail) with the remote mail server, and OpenSMTPD to relay emails sent with /usr/sbin/sendmail (also to the mail server). This enables Aerc to show the emails and both Aerc and Git to send emails - even when offline.

I really like this setup for my “normal” email conversations, but I believe it really shines when used with the git email workflow where Aerc and Git can be used (possibly offline) to review and send patches. And if you do not know about the git email workflow, I recommend you read some of these resources.

Annex: other resources

In the process of setting up my system, I found the following resources very helpful:


  1. Or was it even Hotmail, before that? ↩︎

  2. Note that I write “isync/mbsync” everywhere because the tool is called “isync”, but the command to call it is “mbsync”. ↩︎