---
title: "Dovecot"
lastUpdated: 2025-08-24
slug: ispmail-trixie/dovecot
sidebar:
  order: 165
---

import { Aside } from "@astrojs/starlight/components";
import StepListReceive from "../../../components/StepListReceive.astro";

<StepListReceive currentStep={4} />

In this chapter we will mainly configure Dovecot so that it knows how to deliver incoming emails.

## Setting up the vmail directory

On your disk all the mailboxes will live in the directory `/var/vmail`. To separate the mailboxes from the rest of your
system, let's create a new user and group that will own the mailboxes:

```sh title="Run this on your server"
groupadd --system vmail
useradd --system --gid vmail vmail
mkdir -p /var/vmail
chown -R vmail:vmail /var/vmail
chmod u=rwx,g=rx,o= /var/vmail
```

## Dovecot configuration

The configuration files for Dovecot are found in `/etc/dovecot/conf.d`. All these files are loaded by Dovecot. This is
done by this magical line at the end of the `/etc/dovecot/dovecot.conf` file:

```
!include conf.d/*.conf
```

It loads all files in `/etc/dovecot/conf.d/` that end in “.conf" in alphanumerical order. Let's edit a couple of files
for our purpose.

### 10-auth.conf

The `/etc/dovecot/conf.d/10-auth.conf` file is dealing with authentication. At the end of this file you will find a list
of authentication backends that Dovecot ships with. By default it will use system users (those from /etc/passwd). But we
want to use the MariaDB database backend so go ahead and change this block to:

```
#!include auth-system.conf.ext
!include auth-sql.conf.ext
#!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
#!include auth-static.conf.ext
```

Every line starting with `#` is disabled. Only lines starting with `!` are considered.

### 10-mail.conf

Edit this file at `/etc/dovecot/conf.d/10-mail.conf`. It contains many settings regarding mailboxes, like where they are
located, who owns them and what is their layout? Set this:

```
mail_driver = maildir
mail_home = /var/vmail/%{user | domain}/%{user | username}
mail_path = ~/Maildir
mail_uid = vmail
mail_gid = vmail
```

This looks more sophisticated than with versions of Dovecot before 2.4. What it means:

- **mail_driver**: Mailboxes are stored in
  [maildir](https://doc.dovecot.org/2.4.1/core/config/mailbox_formats/maildir.html#maildir-mailbox-format) format.
- **mail_home**: Every mail user gets their own _home_ directory in `/var/vmail/DOMAIN/USER`. The `user` variable
  contains the email address like `john@example.org`. The expression `user | domain` splits off the _domain_ part from
  the email address. Similarly `user | username` takes the part before the `@` sign.
- **mail_path**: Within the _home_ directory the actual mailbox will live in a subdirectory called `Maildir`. The reason
  is that we will store other data in the user's _home_ directory as well that should not conflict with the mailbox
  directory.
- **mail_uid**/**mail_gid**/: All mailboxes are stored on disk under the owner _vmail_.

### 10-master.conf

This configuration file at `/etc/dovecot/conf.d/10-master.conf` deals with Dovecot's services.

So most settings are sane here and do not have to be changed. However one change is required in the “service auth"
section because we want Postfix to allow Dovecot as an authentication service. Make it look like this:

```
# Postfix smtp-auth
unix_listener /var/spool/postfix/private/dovecot-auth {
  mode = 0660
  user = postfix
  group = postfix
}
```

That way Dovecot will put a communication socket into `/var/spool/postfix/private/dovecot-auth`. It will allow Postfix
to authenticate your users which is relevant later when we set up _relaying_.

### 10-ssl.conf

Earlier in this guide you created both a key and a certificate file to encrypt the communication with IMAPS and HTTPS
between the users and your mail server. You need to tell Dovecot where to find these files. Also set
[ssl=required](https://doc.dovecot.org/2.4.1/core/config/ssl.html#how-to-specify-when-ssl-tls-is-required) to prevent
that someone sends their password without encryption.

<Aside type="danger" title="Important">

Please replace `mail.example.org` by the FQDN you chose.

</Aside>

```
ssl = required
ssl_server_cert_file = /etc/letsencrypt/live/mail.example.org/fullchain.pem
ssl_server_key_file = /etc/letsencrypt/live/mail.example.org/privkey.pem
```

### 20-lmtp.conf

There is one setting in the `/etc/dovecot/conf.d/20-lmtp.conf` that will mess up the recipient's email address in our
setup. So please edit this file and comment out the `auth_username_format` line:

```
protocol lmtp {
  #auth_username_format = %{user | username}
}

```

### auth-sql.conf.ext

Let's tell Dovecot where to find information on an valid users (_userdb_) and their passwords (_passdb_). You can safely
replace the content of the `/etc/dovecot/conf.d/auth-sql.conf.ext` file by:

```
sql_driver = mysql

mysql /var/run/mysqld/mysqld.sock {
  user = mailserver
  password = 'MAILSERVER-PASSWORD-HERE'
  dbname = mailserver
  host = 127.0.0.1
}

userdb sql {
  query = SELECT email as user FROM virtual_users WHERE email='%{user}'
  iterate_query = SELECT email as user FROM virtual_users
}

passdb sql {
  query = SELECT password FROM virtual_users where email='%{user}'
}
```

Dovecot can also read the path to a user's home directory and the user-ID and group-ID from the database. Our setup has
a fixed schema for the home directory (`/var/vmail/DOMAIN/USER`) and the user-ID and group-ID are always `vmail` and
`vmail`.

Make sure that only root can access the SQL configuration file so nobody else is reading your database access passwords:

```sh title="Run this on your server"
chown root:root /etc/dovecot/conf.d/auth-sql.conf.ext
chmod go= /etc/dovecot/conf.d/auth-sql.conf.ext
```

## Restart and test

Restart Dovecot from the shell:

```sh title="Run this on your server"
systemctl restart dovecot
```

Check your logs:

```sh title="Run this on your server"
journalctl -fu dovecot
```

You should see:

```
dovecot[13309]: master: Dovecot v2.4.1-4 (7d8c0e5759) starting up for imap, lmtp, sieve (core dumps disabled)
systemd[1]: Started dovecot.service - Dovecot IMAP/POP3 email server.
```

If you get any error messages please double-check your configuration files.

<Aside type="tip" title="Why there is no /var/log/mail.log?">

In previous guides we used to check the log output from Postfix and Dovecot in a file called `/var/log/mail.log`.
However in the age of _systemd_ the output of the processes is written to systemd's _journal_ instead.

To read the complete logs of Dovecot, run (u=unit):

```sh title="Run this on your server"
journalctl -u dovecot
```

To `tail -f` the logs (f=follow):

```sh title="Run this on your server"
journalctl -fu dovecot
```

However on a busy server it will show the entire journal and then follow any changes. You may want to limit the output
to the last 10 lines:

```sh title="Run this on your server"
journalctl -n 10 -fu dovecot
```

If you prefer the old way of having log files, just install the `rsyslog` package.

</Aside>

<Aside icon="approve-check-circle" title="Test it">

To test the `userdb` query:

```sh title="Run this on your server"
doveadm user john@example.org
```

That should give you:

```
field     value
uid       vmail
gid       vmail
home	    /var/vmail/example.org/john
mail_path	/var/vmail/example.org/john/Maildir
```

To test the `iterate` query that gets a list of all users:

```sh title="Run this on your server"
doveadm user '*'
```

As there is currently only one user the output should be:

```
john@example.org
```

</Aside>
