What is Remails?
About a year ago, the founder of Remails contacted us to help build Remails, a Mail Transfer Agent (MTA) hosted fully in Europe. An MTA is a service that helps deliver emails reliably by forwarding emails via IP addresses that have earned a good reputation, ensuring the right email headers are set, and retrying delivery automatically when things go wrong. Remails’ source code is available on GitHub, which allows anyone to self-host it, but they also provide a ready-to-use working instance of Remails at remails.net.
Remails is currently mainly meant for transactional emails, not broadcast emails. This means it is perfect for sending email verification codes, password reset links, and personal notifications and reminders, but it is not yet meant for sending advertising emails to hundreds or thousands of people at the same time. Eventually, we might lift this limitation in the process of further development.
In the following sections, let’s take a look at how the development has gone so far and the technical challenges we faced along the way.
From MVP to high availability
At the start of the project, our main focus was to quickly build a minimum viable product, keeping the feedback loop short and showing results early on. Therefore, we started off with a cheap, single Virtual Private Server (VPS) from a European cloud provider. The whole application was running as a single binary in a container “orchestrated” by Docker Compose next to a simple PostgreSQL database container.
Simple VPS deployment at development start
After the fundamental work of implementing SMTP communication, a basic web interface, and the database integration was done, we went on to improve the deployment setup. For Remails, we had a hard requirement to use a European cloud provider. Ideally, we want to administer as little infrastructure as possible ourselves while also ensuring high availability of the service.
High availability
We set up a managed Kubernetes cluster with a managed Postgres database from the cloud provider. We split our application into two logical parts: the web interface API used to manage credentials and the actual MTA part, which sends and receives messages via SMTP. Using Kubernetes, we can run multiple replicas of each component and distribute them over multiple machines (called nodes in Kubernetes speak). This means that services will still be available on other nodes when one of the nodes goes down, thus achieving high availability.
... continue reading