Email, Contacts, and Calendar
I've finally migrated my email, contacts, and calendar out of Google and want to share the process. It's a low-cost solution but does require some learning and patience. I'm hopeful that someone else desiring independence from the big tech companies can learn from my adventures.
Data of Communication ¶
Why did I group email, contacts, and calendar together? The reason is that they're very tightly coupled when it comes to communication.
- If I'm trying to contact someone, I would email them.
- To know their email and name, I would have their contact saved.
- To schedule a meeting with them, I would schedule time in my calendar.
It's hard to use email without contacts, or email without calendar, or a calendar without contacts. I call these three the data of communication because each are essential to personal and professional communication over the internet. All three are remotely intertwined from a technical standpoint as well for this reason. It makes sense to migrate all of them at once.
Proton ¶
At first I migrated to Proton because of its claim of privacy but I ran into a few issues.
First, emails are encrypted at rest (encryption in storage), meaning it's not as simple to access them externally if you try to export them or view them through a client like Thunderbird. To get SMTP or IMAP to work you need to run a separate "bridge" software which isn't ported to all operating systems and consumes a nontrivial amount of system memory[1]. This is not to mention the fact that Proton does not provide end-to-end encryption (encryption during transit) so Proton can still read the emails you send if they wanted. There are plenty of examples of Proton providing data to authorities when requested.
Proton also currently (at the time of writing this) has no contacts integration. Proton stores contact information from emails but there's no official interface to edit them or export them. There are forum suggestions to integrate better contacts support but it hasn't happened yet.
In their defense, Proton Calendar is pretty good. The features are on-par with Google Calendar. My only criticism is that external calendars aren't cached and load slowly every time you open the website or mobile app. It is a bit inconvenient when you need to keep track of multiple calendars at once.
I used a paid Proton plan for almost 2 years before I decided it wasn't worth the price.
The Protocols ¶
I decided to learn how the underlying protocols interact with each other to determine if this was something I could manage or host myself.
Email at a high level is computers sending text files to each other. It's received through IMAP and sent through SMTP (though other protocols exist such as POP3 and JMAP). There are a lot of tools you can optionally attach around this workflow:
- postfix is a mail transfer agent that can auto-retry sending emails that failed to deliver to their destination.
- isync can synchronize mail from an email server to a local device for offline mail access.
Calendar and contacts use entirely different protocols called CalDAV and CardDAV respectively which are built on top of the WebDAV protocol. This protocol acts similar to a folder of files: contacts are stored in ics
files and calendars are stored in ical
files. The protocols are a pleasure to work with if you can find good calendar and contacts clients to display and modify your data.
In the end I decided that even if the protocols and related software would be easy to work with, I didn't want to have to worry about server uptime and regular maintenance. As much as I love self-hosting, I rely too heavily on my email and calendar for life and work that I would be paying a heavy toll down the road if I ran into an obstacle with a self-hosting solution. I decided to look at hosted solutions.
Purelymail ¶
Purelymail is the hosting solution I ended up landing on. It's a paid service that allows you to store email, contacts, and calendar via the aforementioned protocols on their servers. One thing that pulled me towards them is their reliability and their pricing model. No enshittification here. They only charge for what you use so you only have to pay $2-5 annually for "regular" email volume. Because the service exposes the protocols, it means you remain in control of your data - you're always able to export your data and exit at any time. It also has a great user management interface to easily allow you to manage email for yourself or a group of users securely.
Purelymail does not offer email encryption so it is up to you to encrypt emails yourself. This is how email should work anyways - it's not a good idea to trust someone else to encrypt your messages for you. Encryption can be done for emails with gpg.
The Setup ¶
This is my current workflow with email, contacts, and calendar:
Email ¶
Email is served via Purelymail. I use Thunderbird to read emails from my phone and Aerc to read emails from the terminal. If I'm using a device that can't run Aerc, I can use Thunderbird for desktop or use Purelymail's webmail interface. It's a bit ugly but it works fine.
I can't recommend Aerc enough. I've never had enough patience to figure out Alpine or NeoMutt but Aerc just clicks. It simplifies a lot of the hassle of terminal email setups and has nice defaults.
I also use isync (mbsync) to sync and download my email periodically. It's incredibly useful if you spend a lot of time drafting emails in cafes with spotty internet.
This is my Aerc configuration:
[Personal]
source = maildir://~/Documents/Mail
outgoing = smtps://sam%40bossley.xyz@smtp.purelymail.com:465
outgoing-cred-cmd = cat ~/.local/share/davtoken.txt
from = Sam Bossley <sam@bossley.xyz>
default = INBOX
copy-to = Sent
folders = INBOX,Drafts,Sent,Archive,Junk,Trash
folders-sort = INBOX,Drafts,Sent,Archive,Junk,Trash
cache-headers = true
check-mail = 0
check-mail-cmd = mbsync Personal
signature-file = /home/sam/.config/aerc/signature.txt
Then isync configuration:
MaildirStore local
Path ~/Documents/Mail/
INBOX ~/Documents/Mail/INBOX
SubFolders Verbatim
IMAPAccount PurelymailAccount
Host imap.purelymail.com
Port 993
User sam@bossley.xyz
PassCmd cat\ "~/.local/share/davtoken.txt"
TLSType IMAPS
IMAPStore PurelymailStore
Account PurelymailAccount
Channel Personal
Far :PurelymailStore:
Near :local:
Patterns *
Create Both
Remove Both
Expunge both
Finally, my crontab entry:
*/2 * * * * /usr/bin/mbsync Personal
Contacts and Calendar Syncing ¶
I decided early on that I only want my contacts and calendar to be editable from my phone and read-only from my other devices to prevent myself from clumsily deleting contacts or breaking calendar events. I use DAVx5 to sync my phone with Purelymail. DAVx5 allows you to continue using any native calendar and contacts apps on your phone seamlessly with DAV servers. I still use the Google Calendar and Google Contacts apps for my phone because they're feature-rich compared to other generic calendar or contacts apps.
For my other devices, I use vdirsyncer to pull my contacts and calendar periodically to those devices. Here is my vdirsyncer configuration:
[general]
status_path = "~/.local/share/vdirsyncer/status/"
[storage local_contacts]
type = "singlefile"
path = "~/Documents/Contacts/%s.vcf"
[storage Purelymail_contacts]
type = "carddav"
url = "https://purelymail.com/"
username = "sam@bossley.xyz"
password.fetch = ["command", "cat", "~/.local/share/davtoken.txt"]
read_only = true
[pair Personal_contacts]
a = "local_contacts"
b = "Purelymail_contacts"
collections = ["from a", "from b"]
conflict_resolution = "b wins"
[storage local_calendar]
type = "singlefile"
path = "~/Documents/Calendars/%s.ics"
[storage Purelymail_calendar]
type = "caldav"
url = "https://purelymail.com/"
username = "sam@bossley.xyz"
password.fetch = ["command", "cat", "~/.local/share/davtoken.txt"]
read_only = true
[pair Personal_calendar]
a = "local_calendar"
b = "Purelymail_calendar"
collections = ["from a", "from b"]
conflict_resolution = "b wins"
metadata = ["color", "displayname", "description"]
If I really need to, I can also use Thunderbird for clients that do not support vdirsyncer.
Contacts ¶
I only save my contacts file for backup because I rarely need to edit my contacts. In crontab I pull every 2 hours:
0 */2 * * * /usr/bin/vdirsyncer sync Personal_contacts
Calendar ¶
For calendar, I use calcurse to be able to view upcoming meetings for the day. I run a script to sync the server with my local calcurse instance:
#!/usr/bin/env sh
/usr/bin/vdirsyncer sync Personal_calendar
if ! pgrep "calcurse" > /dev/null
then
rm -rvf "/home/sam/.local/share/calcurse"
mkdir -p "/home/sam/.local/share/calcurse"
/usr/bin/calcurse -i /home/sam/Documents/Calendars/default.ics
fi
Then I have a crontab entry to run this periodically:
*/3 * * * * /usr/local/bin/refetch-calendar
I use this color for my default calendar if you're interested:
Alternatives ¶
There are a few alternatives I considered before settling on Purelymail:
- Fastmail seems to be the industry standard for this but it's priced the same as Proton. No thanks!
- Posteo has a great setup but email attachment sizes are limited.
- Stalwart looks like a promising alternative but doesn't seem ready for public consumption yet. It also only manages email.
Conclusion ¶
I learned a lot about different protocols on my adventure and have learned to appreciate a lot of the complicated services Apple and Google provide. I'm happy that I now control my own data and don't regret migrating it out of Google.
Proton claims that their bridge "shouldn't use more than 2 GB of RAM at any time". That threshold is almost comparable to the amount of system memory an instance of Chrome might use. ↩︎