Setting up a Free Email Server on Google Compute Engine

Published: Feb 5, 2022

Here’s a quick tutorial on how to setup an almost free email server on Google Cloud’s Always Free compute engine instance using Cloudron. It also uses Amazon Web Service’s (AWS) Simple Email Service (SES) as an SMTP relay so you don’t have to worry about deliverability of your emails (probably the most important reason why self-hosting email is generally not a good idea).

So this is not entirely free, since I recommend using S3 for backup (which could cost you $1 or so per month) and Amazon SES as an SMTP relay (which should cost a few pennies per month), but it’s extremely cheap for what you get.

The Features

  • Email server for your custom domain(s)
  • Unlimited domains, mailboxes (users), and email aliases
  • Catch-all email address
  • Spam filtering (with SpamAassassin)
  • About 16GB of combined space for all of your users
  • Webmail with Roundcube
  • IMAP/POP/SMTP access
  • SMTP relay with Amazon SES for worry-free deliverability
  • Virtually zero maintenance after initial setup
    • Automatic backups to S3
    • Automatic updates of Cloudron software and installed applications
    • Automatic updates of the Ubuntu server

Costs

  • Server: If using Google Compute Engine’s Always Free tier, it is free. This is good enough for a couple of users with less than 16GB of total email space (among all users). A VPS (i.e. from Hetzner) for about €4.90/month can give you excellent performance for a larger group of users and more flexibility on disk space.
  • Backups: You can set an NFS mount point to your home PC for free, but I highly recommend Google Cloud Storage or Amazon S3. I use S3 and it costs about $0.02/month per gigabyte of data. Depending on the frequency of backups and the retention policy you set, you’ll likely have about 5-10x your total email storage size backed up on S3 at any given time. So if you have 5GB of emails, plan on up to $1 of storage costs per month.
  • SMTP relay: If using Amazon SES, you should pay practically nothing (like pennies) per month.

What you need

  • A Google Cloud Platform account: free to setup and comes with a free trial. Once the free trial ends, your Always Free compute engine continues to run free.
  • An Amazon Web Services (AWS) account: for S3 and SES
  • A domain with access to DNS settings

First Step: Google Cloud Platform

VPC Network --> Firewall

This will save you some time, if you setup some firewall rules assigned to network tags. Then, when you create your Compute Engine instance, you can assign the tags to the instance and have all the ports you need opened upon deployment.

  1. Incoming Mail:
    • Name: incoming-mail
    • Priority: 1000
    • Direction: Ingress
    • Target tags: incoming-mail
    • Source Filters > IP ranges: 0.0.0.0/0
    • Protocols and ports: tcp:25
  2. IMAP-Server:
    • Name: imap-server
    • Priority: 1000
    • Direction: Ingress
    • Target tags: imap-server
    • Source Filters > IP ranges: 0.0.0.0/0
    • Protocols and ports: tcp:993
  3. SMTP Server:
    • Name: smtp-incoming
    • Priority: 1000
    • Direction: Ingress
    • Target tags: smtp-incoming
    • Source Filters > IP ranges: 0.0.0.0/0
    • Protocols and ports: tcp:587

Notes: All rules are ingress only. Your SMTP server does not need an outgoing egress rule because you will be using Amazon SES as an SMTP relay. This is only for connecting devices and clients to your server via IMAP and SMTP. Also, your SSH (port 22), http (port 80), and https (port 443) will be opened as part of deploying your Compute Engine instance.

Compute Engine --> VM Instances

Now you are ready to create your Always Free Compute Engine instance. Refer to Google’s Free Tier Site for specs you can choose, as it may be different than the specs listed here at the time of this writing. For me, here were the settings that I chose:

  • Name: ubuntu-free
  • Region: us-west1 (Very important to pick one of the regions allowed in the link above)
  • Zone: us-west1-b
  • Series: E2
  • Machine Type e2-micro (This is the only free machine type you can choose)
  • Boot Disk:
    • Operating System: Ubuntu
    • Version: Ubuntu 20.04 LTS (The only option for Cloudron)
    • Type: Standard persistent disk (Very important to change to this if you want it to be free)
    • Size (GB): 30 (Max allowed in the free tier)
  • Firewall: select both HTTP and HTTPS traffic
  • Security > SSH keys: This will save you a lot of time if you put in at least one SSH public key from wherever you plan to SSH in from.

VPC Network --> External IP Address

Now that you setup you setup your Compute Engine instance, you need to go back to the VPC Network’s External IP Address section. You will see the external IP address assigned to your instance, but it will be shown as ephemeral. You should select the option to reserve the IP address and it will change to static.

Note: if you ever shut down the Compute Engine instance, be sure to release this IP address or you will be charged monthly for it. Only this one is free when in-use and tied to your instance.

Second Step: Install Cloudron

Now that you know your IP address, you can ssh into your instance. If you set your SSH key correctly when creating the instance, this should just work:

ssh <username>@<your external IP address>

Once you are in, read the installation instructions from Cloudron’s website. The basic commands I used were:

wget https://cloudron.io/cloudron-setup
chmod +x cloudron-setup

But do NOT run the setup file yet. It will not work until we hack it a bit. Cloudron’s minimum RAM requirement for a server is 1GB. And this Always Free Compute Engine instance is 1GB but is off by a few megabytes. You need to change the parameter in the setup file. You can use nano:

nano ./cloudron-setup

Then change the following line: readonly MINIMUM_MEMORY="950"
I forget what it said before, but it was probably something like 974. Changing it to 950 should allow the installation to work.

Then run the setup:

sudo ./cloudron-setup

Once Cloudron is installed, it will have some directions. Basically, you go into a browser, using the IP address and accept the certificate. Then continue the setup from there. It should be pretty self-explanatory, but here are some notes:

  • It will ask you for the domain name you want to use. Input it.
  • It will ask you to select your DNS provider, but I just set it to manual (where it says Not Recommended, but honestly, this is so easy and I prefer to just do it myself).
  • Follow the instructions from there, but basically you will put the external IP address of your Compute Engine as an A record under my.<yourdomain>. Then you will wait for DNS to propogate and for Cloudron to setup your SSL certificates and prompt you to continue setting up.
  • You will need an admin user and password as well as an account at Cloudron.io, which allows you to use a free license, good for 2 applications.
  • The email server itself does not count as an application, so you actually have two applications you can install. At a minimum, you should install a webmail like Roundcube. If you follow the instructions for installing Roundcube, it will likely prompt you to set another A record for mail.<yourdomain> to the same IP address.
  • You can pick another application you can host, but with the limited resources of the Compute Engine instance, there’s not much more it can handle. I have it host a Commento server on mine, which is very lightweight and runs the comments on this website (see the comments section below).
  • You will then need to go to the Email section and enable incoming mail and setup a mailbox. It will also have directions on DNS settings. Since we will be setting up an SMTP Relay using AWS SES, more details will be in the next step.

Third Step: Setup Amazon SES SMTP Relay

If you haven’t setup Amazon SES, it is pretty straightforward. You start by verifying your first domain. It will tell you all the CNAME DKIM records you need to setup. You should also setup an SPF record for your root domain. You should also set a custom mail-from subdomain (i.e. at ses.) which passes your typical relaxed DMARC setting you will likely want to set and will generally improve your spam score on your outgoing mail.

Once you verify your domain, you will be in a sandbox environment which means you can only use it to email recipients that you have verified (you can add verified email addresses as identities in SES). To be able to use SES in production, you need to make a request with AWS customer service and it could take a couple days.

Meanwhile, you can setup an SMTP user and get the Access KEY ID and Secret Access Key, which you will use as the User and Password in the SMTP relay section in Cloudron’s setup.

In Cloudron:

  • Go to the Email section in the right corner menu. Then click on your domain.
  • Go to Outbound and select Amazon SES.
  • SMTP Host: email-smtp.us-west-2.amazonaws.com (this is mine. Find the host from your SES settings)
  • SMTP Port: 587
  • Username: <Your Access Key ID>
  • Password: <Your Secret Access Key>

You don’t need to keep your AWS credentials around. You can always generate another set of credentials. And you never need to use these credentials directly in any SMTP settings you set with your email clients (mobile phone or desktop client). Since we opened port 587 ingress on your Compute Engine, you can use the following SMTP settings:

  • SMTP Server: my.<yourdomain>
  • Port: 587
  • Username: <[email protected]>
  • Password: <The Cloudron password for your user>

This will correctly use the SES relay with the service account credentials you just setup in Cloudron. It simply allows each user to access it with Cloudron’s credentials so that you don’t have to give out the AWS service account password out.

Fourth Step: Setup Amazon S3 Backup

One of the best features of Cloudron is how easy it is backup your entire server (including mailboxes). There are many ways you can setup backup, but if you are already using SES, it’s easy enough to create an S3 bucket to store your backups.

First go to S3 and create a bucket. Call it a recognizable name. Also, for extra security, make sure you select the setting to block all public access.

You’ll then want to go to Identiy and Access Management (IAM) and create a user to access the bucket. Before creating a user, it’s nice to create a user group with permissions to access only certain buckets. For instance, you can create a user group called s3-backup-cloudron-group and create a policy for it. Here is the policy I set for the group:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::<name of my bucket>",
"arn:aws:s3:::<name of my bucket>/*"
]
}
]
}

You can then create a user that inherits this group’s policy and use this only for Cloudron backups. Once you create the user you can generate credentials. Similar to when you did your SMTP credentials, you will have an Access KEY ID and Secret Access Key. You can download it as a csv or just leave your window open so you can copy it to your Cloudron instance’s settings.

In Cloudron, in the top right menu, select Backups. Then:

  • For Location, select configure:
    • Storage Provider: Amazon S3
    • Bucket Name: <Your Bucket Name>
    • Region: US West (Oregon) (or wherever your bucket is)
    • Access Key ID: <Your Access Key ID>
    • Secret Access Key: <Your Secret Access Key>
    • Storage Format: Tarball (zipped)
  • For Schedule and Retention, select whatever makes the most sense. I prefer 11PM nightly with a retention policy of 3 daily, 4 weekly, 6 monthly.

You can then click Backup Now and see if it works. If it appears to work, go to your AWS Admin Console and browse your S3 bucket. You should see a new folder with the current date and time of the backup you just made.

And that’s it. You have yourself an email server that costs extremely little and has as many mailboxes, email addresses, and domains you need. You should have almost no maintenance and can easily redeploy a new instance if you move servers, using your backups.

Image Credit: mohamed hassan

Previous Post

Randi Zuckerberg, Stay Away From Our Kids

So I was signing up for my daughter's virtual bookshelf for school and saw this on their website...

Next Post

Privacy

Facebook is a cancer, LinkedIn is a neoliberal cesspool, and Twitter is diarrhea.