Create your own mail server

Create your own mail server

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.


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


You need a VPS

  • Internet accessible with public IP address
  • 1G RAM
  • Some storage

System (Running OS)

  • Ubuntu 20.04 LTS as example


  • 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


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 and env-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 set ENABLE_POP3=1
    • 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 mapped letsencrypt for SSL/TLS.
    version: '2'
    image: tvial/docker-mailserver:latest
    hostname: ${HOSTNAME}
    domainname: ${DOMAINNAME}
    container_name: ${CONTAINER_NAME}
    - "25:25"
    - "143:143"
    - "587:587"
    - "993:993"
    - "995:995"
    - maildata:/var/mail
    - mailstate:/var/mail-state
    - maillogs:/var/log/mail
    - ./config/:/tmp/docker-mailserver/
    - /home/ubuntu/acme.sh/:/tmp/ssl:ro
    - .env
    - env-mailserver
    restart: always
    driver: local
    driver: local
    driver: local
Start Container
sudo docker-compose up -d mail
Create your mail accounts
sudo ./setup.sh email add <user@domain> [<password>]
sudo ./setup.sh email add <user2@domain2> [<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.

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.

Written by Felix. Licensed under CC BY-NC-SA 3.0 Unported.

Leave a Reply



Create your own mail server
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,…
Scan QR code to continue reading