So you've decided to self-host Mailmask? That's great! This guide will get you up and running.
I'm going to assume you have experience using the terminal/commandline as well as setting up databases.
Note: These instructions are written for Mac and/or Linux. If you're hosting on a Windows server you may have to replace some of the commands with the Windows equivalent.
- Node.js 12 or later installed and available in
- Yarn package manager
- PostgreSQL 9.6 or later, with SSL support ENABLED.
- I recommend Digital Ocean's cloud instances
The following instructions are assuming you are running as the
root user on your servers for the sake of brevity. Of course, you should
ideally create a new user and restrict the permissions, etc.
Additionally, I will assume that you will be hosting the mail server (MTA) and website on the same server machine.
I will also assume that your chosen domain name is
## Setup domain name
Register a domain name to use. (I recommend Namecheap for domains).
Setup email for your domain, using any email provider you like.
Note: For the remainder of this guide I am going to assume your domain is
yourdomain.com and that you are able to receive all emails sent to
Sengrid is used by Mailmask to send emails to users. Register a SendGrid account.
In your Sendgrid account you want to configure it such that send emails can be sent from:
@reply.yourdomain.com(this is required for private replies to work)
Also, create an API in SendGrid - you will need this for configuring the Mailmask servers below.
There are various config parameters that need to be set for the various servers. These are:
MAILER_API_KEY- your SendGrid API key
ENCRYPTION_KEY- AES encryption key, 32-character hex string (e.g.
ENCRYPTION_IV- AES encryption initialization vector, 16-character hex string (e.g.
APP_MODE- set this to
DB_HOST- hostname/ip of database server
DB_PORT- port of database server
DB_USERNAME- database user username
DB_PASSWORD- database user password
DOMAIN- your domin name
SUPPORT_EMAIL- the email address from which login/signup/welcome emails get sent, e.g.
Clone the Mailmask repository locally
Clone the Mailmask repo:
git clone https://github.com/hiddentao/mailmask
Go into the project folder:
Install all dependencies:
npm run bootstrap
Setup the database
Connect to your PostgreSQL database and:
- Create a new user called
- Create a database called
- Grant the
mailmaskuser full access to
The above can be accomplished by running the following SQL commands against your PostgreSQL instance:
create database "mailmask-live"; create user mailmask with encrypted password '<password here>'; grant all privileges on database "mailmask-live" to mailmask; grant all on schema public to mailmask; grant all on all tables in schema public to mailmask;
Go into the
data package folder:
Setup shell environment:
export DB_HOST=<host / ip address of db server> export DB_PORT=<port of db server> export DB_USERNAME=mailmask export DB_PASSWORD=<password you set earlier>
Run the migrations to create the tables (this uses knex):
yarn knex:migrate --env selfhost
If all goes well you should see output that looks a bit like:
Using environment: selfhost Batch 1 run: 2 migrations ✨ Done in 5.01s.
Your database is now ready!
Setup the mail server (MTA)
The mail server is what receives all email and processes it.
Open a new terminal window and change into the
.env and enter the config variables into it as follows (refer to the earlier section on config variables for more info):
MAILER_API_KEY=... ENCRYPTION_KEY=... ENCRYPTION_IV=... DOMAIN=... SUPPORT_EMAIL=...
config/host_list_regex and set its contents to:
config/smtp.ini and set the address to listen on:
Now start the server:
You should see something like:
2020-07-06T19:50:27.098Z [NOTICE] [-] [core] Listening on :::25 2020-07-06T19:50:27.139Z [NOTICE] [-] [core] worker 1 listening on ::0:25
The mail server starts as many worker threads as their are CPU cores on your server, so you may see the above log message repeated a few times.
Your mail server is now ready to accept connections.
Dockerfile is available for the mta in case you wish to deploy it as a docker container.
Build the docker image:
docker build --tag mailmask-mta:latest .
To run the container you will need to supply the config paramter your placed in
.env earlier as
docker run \ --publish 25:25 \ --env DB_HOST=... \ --env DB_PORT=... \ --env DB_USERNAME=... \ --env DB_PASSWORD=... \ --env MAILER_API_KEY=... --env ENCRYPTION_IV=... --env ENCRYPTION_KEY=... --detach \ mailmask-mta \ mailmask-mta:latest
Update DNS to point to mail server
The next step is go into your domain's DNS configuration and setup a special wildcard MX record which points
to your mail server's IP address. And you can also add an
A record which maps the
Note that this DNS configuration record is specifically for Mailmask - it does not interfere with any other existing
MX records you may
have already setup for your domain.
The end result is:
- Emails sent to
@yourdomain.comwill go to wherever you're configured
- Emails sent to
@ANYTHING.yourdomain.comwill goto the Mailmask MTA server you just setup
Setup the website
The website is built in Next.js.
Go into the
web package folder:
.env.production and enter the config variables into it as follows (refer to the earlier section on config variables for more info):
MAILER_API_KEY=... ENCRYPTION_IV=... ENCRYPTION_KEY=... APP_MODE=selfhost DB_HOST=... DB_PORT=... DB_USERNAME=... DB_PASSWORD=...
Build the website:
Now run the website:
PORT=3002 yarn start
If you visit http://localhost:3002 you should now be able to sign up just as you do on the Mailmask website.
If the website is running on the same machine as the mail server and you mapped the DNS records as shown earlier then you
should be able to see the website when visting
It is important to secure your server when self-hosting. However the exact measures you may wish to take will depend on how you're hosting Mailmask (e.g. on a server at home or in the cloud) as well as the operating system running it.
At minimum we recommend:
- Setting up a firewall to only allowing incoming connections on ports:
- 22 - If you're using SSH.
- 25 - For the mail.
- 3002 - For the website. If the website is running on a different port number then use that number instead.
- Protecting access to the website
- Use an SSL certificate - the easy way is to use CloudFlare as your DNS host since SSL comes for free.
## Help and troubleshooting
If you need further help with your self-hosting setup then please get in touch via the Mailmask help page.