diff --git a/dockerfiles/email/base-email/Dockerfile b/dockerfiles/email/base-email/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..d3169d6af5666940b486bd241e8d477a688e5897
--- /dev/null
+++ b/dockerfiles/email/base-email/Dockerfile
@@ -0,0 +1,15 @@
+FROM debian:jessie
+
+ENV DEBIAN_FRONTEND noninteractive
+RUN apt-get update && \
+    apt-get install -q -y \
+      python3 \
+      mysql-client \
+      wget curl && \
+      rm -rf /var/lib/apt/lists/*
+
+COPY editconf.py /opt/editconf.py
+COPY mysql-check.sh /opt/mysql-check.sh
+RUN chmod u+x /opt/editconf.py && \
+    chmod u+x /opt/mysql-check.sh
+
diff --git a/dockerfiles/email/base-email/editconf.py b/dockerfiles/email/base-email/editconf.py
new file mode 100644
index 0000000000000000000000000000000000000000..7bc3d1901eb2ee005f35185bc67a639fcd42ef57
--- /dev/null
+++ b/dockerfiles/email/base-email/editconf.py
@@ -0,0 +1,127 @@
+#!/usr/bin/python3
+#
+# This is a helper tool for editing configuration files during the setup
+# process. The tool is given new values for settings as command-line
+# arguments. It comments-out existing setting values in the configuration
+# file and adds new values either after their former location or at the
+# end.
+#
+# The configuration file has settings that look like:
+#
+# NAME=VALUE
+#
+# If the -s option is given, then space becomes the delimiter, i.e.:
+#
+# NAME VALUE
+#
+# If the -w option is given, then setting lines continue onto following
+# lines while the lines start with whitespace, e.g.:
+#
+# NAME VAL
+#   UE 
+
+import sys, re
+
+# sanity check
+if len(sys.argv) < 3:
+	print("usage: python3 editconf.py /etc/file.conf [-s] [-w] [-t] NAME=VAL [NAME=VAL ...]")
+	sys.exit(1)
+
+# parse command line arguments
+filename = sys.argv[1]
+settings = sys.argv[2:]
+
+delimiter = "="
+delimiter_re = r"\s*=\s*"
+comment_char = "#"
+folded_lines = False
+testing = False
+while settings[0][0] == "-" and settings[0] != "--":
+	opt = settings.pop(0)
+	if opt == "-s":
+		# Space is the delimiter
+		delimiter = " "
+		delimiter_re = r"\s+"
+	elif opt == "-w":
+		# Line folding is possible in this file.
+		folded_lines = True
+	elif opt == "-c":
+		# Specifies a different comment character.
+		comment_char = settings.pop(0)
+	elif opt == "-t":
+		testing = True
+	else:
+		print("Invalid option.")
+		sys.exit(1)
+
+# create the new config file in memory
+
+found = set()
+buf = ""
+input_lines = list(open(filename))
+
+while len(input_lines) > 0:
+	line = input_lines.pop(0)
+
+	# If this configuration file uses folded lines, append any folded lines
+	# into our input buffer.
+	if folded_lines and line[0] not in (comment_char, " ", ""):
+		while len(input_lines) > 0 and input_lines[0][0] in " \t":
+			line += input_lines.pop(0)
+
+	# See if this line is for any settings passed on the command line.
+	for i in range(len(settings)):
+		# Check that this line contain this setting from the command-line arguments.
+		name, val = settings[i].split("=", 1)
+		m = re.match(
+			   "(\s*)"
+			 + "(" + re.escape(comment_char) + "\s*)?"
+			 + re.escape(name) + delimiter_re + "(.*?)\s*$",
+			 line, re.S)
+		if not m: continue
+		indent, is_comment, existing_val = m.groups()
+
+		# If this is already the setting, do nothing.
+		if is_comment is None and existing_val == val:
+			# It may be that we've already inserted this setting higher
+			# in the file so check for that first.
+			if i in found: break
+			buf += line
+			found.add(i)
+			break
+		
+		# comment-out the existing line (also comment any folded lines)
+		if is_comment is None:
+			buf += comment_char + line.rstrip().replace("\n", "\n" + comment_char) + "\n"
+		else:
+			# the line is already commented, pass it through
+			buf += line
+		
+		# if this option oddly appears more than once, don't add the setting again
+		if i in found:
+			break
+		
+		# add the new setting
+		buf += indent + name + delimiter + val + "\n"
+		
+		# note that we've applied this option
+		found.add(i)
+		
+		break
+	else:
+		# If did not match any setting names, pass this line through.
+		buf += line
+		
+# Put any settings we didn't see at the end of the file.
+for i in range(len(settings)):
+	if i not in found:
+		name, val = settings[i].split("=", 1)
+		buf += name + delimiter + val + "\n"
+
+if not testing:
+	# Write out the new file.
+	with open(filename, "w") as f:
+		f.write(buf)
+else:
+	# Just print the new file to stdout.
+	print(buf)
diff --git a/dockerfiles/email/base-email/mysql-check.sh b/dockerfiles/email/base-email/mysql-check.sh
new file mode 100644
index 0000000000000000000000000000000000000000..46a2745629d95c40c467cf020bebe98520b39783
--- /dev/null
+++ b/dockerfiles/email/base-email/mysql-check.sh
@@ -0,0 +1,23 @@
+#!/bin/bash -eux
+
+source /etc/environment
+
+echo "=> Trying to connect to MySQL/MariaDB using:"
+echo "========================================================================"
+echo "      Database Host Address:  $DB_HOST"
+echo "      Database Port number:   $DB_PORT"
+echo "      Database Username:      $DB_USER"
+echo "      Database Password:      $DB_PASS"
+echo "========================================================================"
+
+for ((i=0;i<10;i++))
+do
+    DB_CONNECTABLE=$(mysql -u$DB_USER -p$DB_PASS -h$DB_HOST -P$DB_PORT -e 'status' >/dev/null 2>&1; echo "$?")
+    if [[ DB_CONNECTABLE -eq 0 ]]; then
+        exit 0
+    fi
+    sleep 5
+done
+
+exit 1
+
diff --git a/dockerfiles/email/dovecot/99-local-auth.conf b/dockerfiles/email/dovecot/99-local-auth.conf
new file mode 100644
index 0000000000000000000000000000000000000000..f0e40bf00decf45f3999a8e3705681f2cc182217
--- /dev/null
+++ b/dockerfiles/email/dovecot/99-local-auth.conf
@@ -0,0 +1,8 @@
+service auth {
+  unix_listener /var/spool/postfix/dovecot/auth {
+    mode = 0666
+    user = postfix
+    group = postfix
+  }
+}
+
diff --git a/dockerfiles/email/dovecot/99-local-lmtp.conf b/dockerfiles/email/dovecot/99-local-lmtp.conf
new file mode 100644
index 0000000000000000000000000000000000000000..14f2d9a0e4d51bc15f5d88e23dea539e23aed34d
--- /dev/null
+++ b/dockerfiles/email/dovecot/99-local-lmtp.conf
@@ -0,0 +1,7 @@
+service lmtp {
+  unix_listener /var/spool/postfix/dovecot/lmtp {
+    mode = 0600
+    user = postfix
+    group = postfix
+  }
+} 
diff --git a/dockerfiles/email/dovecot/Dockerfile b/dockerfiles/email/dovecot/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..73433ab094cbcb9d2c1e9c60dec9d5cf1a472d68
--- /dev/null
+++ b/dockerfiles/email/dovecot/Dockerfile
@@ -0,0 +1,56 @@
+FROM pierreozoux/base-email
+
+RUN apt-get update && \
+    apt-get install -q -y \
+      dovecot-core \
+      dovecot-imapd \
+      dovecot-lmtpd \
+      dovecot-mysql && \
+    rm -rf /var/lib/apt/lists/*
+
+COPY 99-local-lmtp.conf /etc/dovecot/conf.d/99-local-lmtp.conf
+COPY auth-sql.conf.ext /etc/dovecot/conf.d/auth-sql.conf.ext
+COPY dovecot-sql.conf.ext /etc/dovecot/dovecot-sql.conf.ext 
+COPY 99-local-auth.conf /etc/dovecot/conf.d/99-local-auth.conf
+COPY init.sql /init.sql
+COPY startup.sh /startup.sh
+
+RUN \
+  groupadd -r postfix && \
+  useradd -r -g postfix postfix && \
+  chmod u+x /startup.sh && \
+  /opt/editconf.py /etc/dovecot/conf.d/10-master.conf \
+    default_process_limit=250 && \
+  /opt/editconf.py /etc/sysctl.conf \
+    fs.inotify.max_user_instances=1024 && \
+  /opt/editconf.py /etc/dovecot/conf.d/10-mail.conf \
+    mail_location=maildir:/mail/mailboxes/%d/%n \
+    mail_privileged_group=mail \
+    first_valid_uid=0 && \
+  /opt/editconf.py /etc/dovecot/conf.d/10-auth.conf \
+    disable_plaintext_auth=yes \
+    'auth_mechanisms=plain login' && \
+  /opt/editconf.py /etc/dovecot/conf.d/10-ssl.conf \
+    ssl=required \
+    'ssl_cert=</ssl/ssl_certificate.pem' \
+    'ssl_key=</ssl/ssl_private_key.pem' \
+    'ssl_protocols=!SSLv3 !SSLv2' \
+    'ssl_cipher_list=TLSv1+HIGH !SSLv2 !RC4 !aNULL !eNULL !3DES @STRENGTH' && \
+  /opt/editconf.py /etc/dovecot/conf.d/20-imap.conf \
+    imap_idle_notify_interval="4 mins" && \
+  sed -i "s/#port = 143/port = 0/" /etc/dovecot/conf.d/10-master.conf && \
+  sed -i "s/#port = 110/port = 0/" /etc/dovecot/conf.d/10-master.conf && \
+  sed -i "s/#*\(\!include auth-system.conf.ext\)/#\1/"  /etc/dovecot/conf.d/10-auth.conf && \
+  sed -i "s/#\(\!include auth-sql.conf.ext\)/\1/"  /etc/dovecot/conf.d/10-auth.conf && \
+  mkdir -p /mail/mailboxes && \
+  chown -R mail:dovecot /etc/dovecot && \
+  chown -R mail.mail /mail/mailboxes && \
+  chmod -R o-rwx /etc/dovecot && \
+  chmod 0600 /etc/dovecot/dovecot-sql.conf.ext
+
+ENTRYPOINT ["/startup.sh"]
+
+VOLUME ["/var/spool/postfix/dovecot"]
+
+EXPOSE 993
+
diff --git a/dockerfiles/email/dovecot/auth-sql.conf.ext b/dockerfiles/email/dovecot/auth-sql.conf.ext
new file mode 100644
index 0000000000000000000000000000000000000000..e6104325b5209edfe5fdb61c45684a478c53e7a4
--- /dev/null
+++ b/dockerfiles/email/dovecot/auth-sql.conf.ext
@@ -0,0 +1,9 @@
+passdb {
+  driver = sql
+  args = /etc/dovecot/dovecot-sql.conf.ext
+}
+userdb {
+  driver = static
+  args = uid=mail gid=mail home=/mail/mailboxes/%d/%n
+}
+
diff --git a/dockerfiles/email/dovecot/dovecot-sql.conf.ext b/dockerfiles/email/dovecot/dovecot-sql.conf.ext
new file mode 100644
index 0000000000000000000000000000000000000000..21fa681a834233b6047a0cf196a1a52fa72b7ab2
--- /dev/null
+++ b/dockerfiles/email/dovecot/dovecot-sql.conf.ext
@@ -0,0 +1,5 @@
+driver = mysql
+connect = host=##DB_HOST## dbname=servermail user=##DB_USER## password=##DB_PASS##
+default_pass_scheme = SHA512-CRYPT
+password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';
+
diff --git a/dockerfiles/email/dovecot/init.sql b/dockerfiles/email/dovecot/init.sql
new file mode 100644
index 0000000000000000000000000000000000000000..c2683730a0d97212dd1ddc644b8beaa33b3acc11
--- /dev/null
+++ b/dockerfiles/email/dovecot/init.sql
@@ -0,0 +1,27 @@
+USE servermail;
+CREATE TABLE `virtual_domains` (
+  `id`  INT NOT NULL AUTO_INCREMENT,
+  `name` VARCHAR(50) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `name` (`name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE `virtual_users` (
+  `id` INT NOT NULL AUTO_INCREMENT,
+  `domain_id` INT NOT NULL,
+  `password` VARCHAR(106) NOT NULL,
+  `email` VARCHAR(120) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `email` (`email`),
+  FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE `virtual_aliases` (
+  `id` INT NOT NULL AUTO_INCREMENT,
+  `domain_id` INT NOT NULL,
+  `source` varchar(100) NOT NULL,
+  `destination` varchar(100) NOT NULL,
+  PRIMARY KEY (`id`),
+  FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
diff --git a/dockerfiles/email/dovecot/startup.sh b/dockerfiles/email/dovecot/startup.sh
new file mode 100644
index 0000000000000000000000000000000000000000..b9c7673b5124652305a4cfe96dc9d40b790e145e
--- /dev/null
+++ b/dockerfiles/email/dovecot/startup.sh
@@ -0,0 +1,36 @@
+#!/bin/bash -eux
+
+export DB_PORT=3306
+export DB_HOST=db
+export DB_USER=admin
+echo $HOSTNAME
+
+sed -i "s/##DB_HOST##/$DB_HOST/" /etc/dovecot/dovecot-sql.conf.ext
+sed -i "s/##DB_USER##/$DB_USER/" /etc/dovecot/dovecot-sql.conf.ext
+sed -i "s/##DB_PASS##/$DB_PASS/" /etc/dovecot/dovecot-sql.conf.ext
+
+/opt/editconf.py /etc/dovecot/conf.d/15-lda.conf postmaster_address=postmaster@$HOSTNAME
+
+/opt/mysql-check.sh
+
+DB_EXISTS=$(mysql -u$DB_USER -p$DB_PASS -h$DB_HOST -P$DB_PORT -e "SHOW DATABASES LIKE 'servermail';" 2>&1 |grep servermail > /dev/null ; echo "$?")
+if [[ DB_EXISTS -eq 1 ]]; then
+  echo "=> Creating database servermail"
+  RET=$(mysql -u$DB_USER -p$DB_PASS -h$DB_HOST -P$DB_PORT -e "CREATE DATABASE servermail")
+  if [[ RET -ne 0 ]]; then
+    echo "Cannot create database for emails"
+    exit RET
+  fi
+  echo "=> Loading initial database data to servermail"
+  RET=$(mysql -u$DB_USER -p$DB_PASS -h$DB_HOST -P$DB_PORT servermail < /init.sql)
+  if [[ RET -ne 0 ]]; then
+    echo "Cannot load initial database data for emails"
+    exit RET
+  fi
+  echo "=> Done!"
+else
+  echo "=> Skipped creation of database servermail it already exists."
+fi
+
+dovecot -F
+
diff --git a/dockerfiles/email/dovecot/user.sql b/dockerfiles/email/dovecot/user.sql
new file mode 100644
index 0000000000000000000000000000000000000000..d4384fb63f0b5eec646c54c51db1087cccc698c4
--- /dev/null
+++ b/dockerfiles/email/dovecot/user.sql
@@ -0,0 +1,17 @@
+INSERT INTO `servermail`.`virtual_domains`
+  (`id` ,`name`)
+  VALUES
+    ('1', 'example.com'),
+    ('2', 'hostname.example.com');
+
+INSERT INTO `servermail`.`virtual_users`
+  (`id`, `domain_id`, `password` , `email`)
+  VALUES
+    ('1', '1', ENCRYPT('firstpassword', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'email1@example.com'),
+    ('2', '1', ENCRYPT('secondpassword', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'email2@example.com');
+
+INSERT INTO `servermail`.`virtual_aliases`
+  (`id`, `domain_id`, `source`, `destination`)
+  VALUES
+    ('1', '1', 'alias@example.com', 'email1@example.com');
+
diff --git a/tests/dovecot.sh b/tests/dovecot.sh
new file mode 100755
index 0000000000000000000000000000000000000000..3508cd9418dbb695c44a6f42f8cc1297f051acd0
--- /dev/null
+++ b/tests/dovecot.sh
@@ -0,0 +1,28 @@
+#!/bin/bash -eux
+
+mkdir -p /data/domains/mail/dovecot
+mkdir -p /data/domains/mail/TLS
+mkdir -p /data/domains/mail/static/www-content
+mkdir -p /data/runtime/domains/mail/mysql/db_files
+mkdir -p /data/domains/mail/mysql
+mkdir /data/domains/mail/nginx
+touch /data/domains/mail/nginx/.env
+
+pass=`echo $RANDOM  ${date} | md5sum | base64 | cut -c-10`
+echo MYSQL_PASS=$pass > /data/domains/mail/mysql/.env
+cat /data/domains/mail/mysql/.env | sed s/MYSQL_PASS/DB_PASS/ > /data/domains/mail/.env;
+echo HOSTNAME=pierre-o.fr >> /data/domains/mail/.env
+echo APPLICATION=nginx >> /data/domains/mail/.env
+echo DOCKER_ARGUMENTS="-v /data/domains/mail/static/www-content:/app" >> /data/domains/mail.env
+
+openssl genrsa -out /data/domains/mail/TLS/ssl_private_key.pem 2048
+openssl req -new -key /data/domains/mail/TLS/ssl_private_key.pem -out /data/domains/mail/TLS/ssl_cert_sign_req.csr \
+  -sha256 -subj "/C=PT/ST=/L=/O=/CN=dovecot.test"
+openssl x509 -req -days 365 \
+  -in /data/domains/mail/TLS/ssl_cert_sign_req.csr -signkey /data/domains/mail/TLS/ssl_private_key.pem -out /data/domains/mail/TLS/ssl_certificate.pem
+openssl dhparam -out /data/domains/mail/TLS/dh2048.pem 2048
+
+cp /data/domains/mail/TLS/ssl_certificate.pem /data/domains/mail/TLS/mail.pem
+
+systemctl start dovecot
+
diff --git a/unit-files/dovecot.service b/unit-files/dovecot.service
new file mode 100644
index 0000000000000000000000000000000000000000..41d05e061b95380a7068af1c3087d222b7fed877
--- /dev/null
+++ b/unit-files/dovecot.service
@@ -0,0 +1,39 @@
+[Unit]
+Description=%p
+
+# Requirements
+Requires=docker.service
+Requires=mysql@mail.service
+Requires=backup@mail.timer
+
+# Dependency ordering
+After=docker.service
+After=mysql@mail.service
+Before=backup@mail.timer
+
+[Service]
+Restart=always
+RestartSec=10
+TimeoutStartSec=60
+TimeoutStopSec=15
+Type=notify
+NotifyAccess=all
+ExecStartPre=/usr/bin/docker run --rm -v /opt/bin:/opt/bin ibuildthecloud/systemd-docker
+ExecStartPre=-/usr/bin/docker kill dovecot
+ExecStartPre=-/usr/bin/docker rm dovecot
+ExecStart=/bin/bash -euxc ' \
+  /opt/bin/systemd-docker --env run \
+    --rm \
+    --name dovecot \
+    -v /data/domains/mail/TLS:/ssl \
+    -v /data/runtime/dev/log:/dev/log \
+    --env-file=/data/domains/mail/.env \
+    --link mysql-mail:db \
+    -p 993:993 \
+    pierreozoux/dovecot'
+ExecReload=/usr/bin/docker restart dovecot
+ExecStop=/usr/bin/docker stop dovecot
+
+[Install]
+WantedBy=multi-user.target
+