Long story short, this post will guide you to create your own mail server instead of looking for mail hosting service around the whole Internet.
Background
Like most geeks, I also own couple domain names. Each domain should have an email service behind it. However, it is not always easy to find a ‘free’ email hosting service to support custom domain.
Long time ago, Google offered free G Suite which supports custom domain. If you are lucky and already had the service, you can continue use it free. But the new registered domain is no longer free.
Then I chose Mailgun service a while ago. But they put more and more restriction on free tier service.
About a year ago, I moved to Migadu. But this week, Migadu announced to terminate free service from 1 Oct 2020.
So it’s the time to host email service by myself. This post will guide you how to create mail server from a VPS. (There’s still lot ‘free’ Cloud VPS available nowadays, like Oracle Cloud, AWS, GCP, etc. )
Step by Step
Preparation
You need a VPS
- Internet accessible with public IP address
- 1G RAM
- Some storage
System (Running OS)
- Ubuntu 20.04 LTS as example
Application
- I tried to install postfix directly on ubuntu as first attempt then realised I also need to install Dovecot, then OpenDKIM, Fail2ban, etc. I gave up.
- I chose docker finally. tvial/docker-mailserver:latest
Installation
You can visit tvial/docker-mailserver:latest github repo directly of how to use this image. It has good documentation and wiki guide you through. My post just summaries some key steps from that repo and save you some time.
Install Docker
sudo apt install docker.io
Get latest image
sudo docker pull tvial/docker-mailserver:latest
Get the tools
Download the docker-compose.yml, the .env and the setup.sh files:
curl -o setup.sh https://raw.githubusercontent.com/tomav/docker-mailserver/master/setup.sh; chmod a+x ./setup.sh
curl -o docker-compose.yml https://raw.githubusercontent.com/tomav/docker-mailserver/master/docker-compose.yml.dist
curl -o .env https://raw.githubusercontent.com/tomav/docker-mailserver/master/.env.dist
curl -o env-mailserver https://raw.githubusercontent.com/tomav/docker-mailserver/master/env-mailserver.dist
Create a docker-compose environment
- Edit the files
.env
andenv-mailserver
to your liking:.env
contains the configuration for docker-compose (HOSTNAME=mail, DOMAINNAME=example.com)env-mailserver
contains the configuration for the mailserver container (Based on your situation, most setting can leave default, I only setENABLE_POP3=1
ENABLE_CLAMAV=0
ENABLE_FAIL2BAN=1
SSL_TYPE=manual- These files supports only simple
VAR=VAL
lines (see Documentation). - Don’t quote your values.
- Variable substitution is not supported (e.g.
OVERRIDE_HOSTNAME=$HOSTNAME.$DOMAINNAME
).
- Install docker-compose in the version
1.7
or higher.sudo apt install docker-compose
- Edit
docker-compose.yml
, I added port 995 from default template because I enabled POP3 service. I also mappedletsencrypt
for SSL/TLS.version: '2' services: mail: image: tvial/docker-mailserver:latest hostname: ${HOSTNAME} domainname: ${DOMAINNAME} container_name: ${CONTAINER_NAME} ports: - "25:25" - "143:143" - "587:587" - "993:993" - "995:995" volumes: - maildata:/var/mail - mailstate:/var/mail-state - maillogs:/var/log/mail - ./config/:/tmp/docker-mailserver/ - /home/ubuntu/acme.sh/:/tmp/ssl:ro env_file: - .env - env-mailserver cap_add: - NET_ADMIN - SYS_PTRACE restart: always volumes: maildata: driver: local mailstate: driver: local maillogs: driver: local
Start Container
sudo docker-compose up -d mail
Create your mail accounts
sudo ./setup.sh email add <[email protected]> [<password>]
sudo ./setup.sh email add <[email protected]> [<password>]
Generate DKIM keys
sudo ./setup.sh config dkim
Now the keys are generated, you can configure your DNS server by just pasting the content of config/opendkim/keys/domain.tld/mail.txt
in your domain.tld.hosts
zone.
With multiple domain, you can obtain individual dkim key (without space and “) from each domain.tld.hosts
zone.
Create DNS MX Records
In your DNS server, create MX records and A records, and SPF TXT record.
Configure SSL/TLS
Create folder /home/ubuntu/acme.sh/
Similar to Post https://www.xfelix.com/2020/04/issue-synology-lets-encrypt-cert-by-acme-sh-docker/, we use acme.sh to issue letsencrypt certificates
Create file /home/ubuntu/acme.sh/account.conf
with your Cloudflare API token and account id.
sudo docker run --rm -itd \ -v /home/ubuntu/acme.sh/:/acme.sh \ --net=host \ --name=acme.sh \ neilpang/acme.sh --issue --dns dns_cf -d mail.example.com daemon
Edit env-mailserver to make sure include these SSL setting.
SSL_TYPE=manual SSL_CERT_PATH=/tmp/ssl/mail.ozbuy.top/fullchain.cer SSL_KEY_PATH=/tmp/ssl/mail.ozbuy.top/mail.example.com.key
Restart and update the container
sudo docker-compose down
sudo docker pull tvial/docker-mailserver:latest
sudo docker-compose up -d mail
Firewall ports open
sudo ufw allow 25
sudo ufw allow 465
sudo ufw allow 587
sudo ufw allow 995
sudo ufw allow 993
If you are using Cloud VPS, do remember to open those ports from network panel.
You’re done!
Configure Gmail to use this new mail server
Configure Send mail as via eSMTP
Configure Check email from other accounts
That’s the reason you have to enable POP3 for Gmail to retrieve email from your mail server. Gmail does not support IMAP unfortunately.
Now you are good to use this mail server. And use Gmail to send / receive email from it.
Hope this post helps you and saves your time. Please leave comments if you like this post. Thanks.
Leave a Reply