Connecting Postfix to Dovecot

There is a newer issue of thie ISPmail guide available if you are using Debian Jessie!

In a previous chapter we made sure that Postfix knows which emails it’s allowed to receive. Now what to do with the email? It has to be stored to disk. Usually that’s done by Postfix itself which comes with a very basic mail delivery agent (MDA) called “virtual” that just saves emails to virtual mailboxes on your hard disk. But as we will use Dovecot (for IMAP and POP3 access) anyway we can use its more featureful local delivery agent (also known as “Dovecot LDA”). It even allows you to use server-side rules to run different automatic actions on incoming email. To make Postfix use that agent you will have to add a service to your /etc/postfix/master.cf:

dovecot   unix  -       n       n       -       -       pipe
 flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/dovecot-lda -f ${sender} -d ${recipient}

Note: the second line has to be indented by spaces.)

Restart Postfix:

service postfix restart

Check the end of the /var/log/mail.log file for any errors. It should read:

postfix/master[…]: daemon started — version 2.9.6, configuration /etc/postfix

Also make Postfix use that service for virtual delivery. Run these two commands to alter your main.cf file:

postconf -e virtual_transport=dovecot
postconf -e dovecot_destination_recipient_limit=1

So now Postfix will pass on incoming emails to virtual users to the /usr/lib/dovecot/deliver program.

(You will find further information on these steps in the Dovecot configuration on Postfix integration.)

25 thoughts on “Connecting Postfix to Dovecot”

    1. Robert Chalmers

      I set up here and originally had “LMTP” but changed it to this and got errors, which I don’t have time to track down just ow, so changed it back to use smtp, and it works fine again.
      Just commented out the line in master.cf and main.cf, reloaded and presto

      eg;
      #Handing off local delivery to Dovecot’s LMTP, and telling it where to store mail
      virtual_transport = lmtp:unix:private/dovecot-lmtp
      #virtual_transport = dovecot
      #This was dovecot-lmtp, but the tutorial used the dovecot one alone, with the line dovecot in master.cf ??
      # lets see if they both work the same.

  1. hi. i am facing the following erros:
    /etc/init.d/postfix restart
    [….] Stopping Postfix Mail Transport Agent: postfixpostmulti: fatal: /etc/postfix/main.cf, line 48: missing ‘=’ after attribute name: “postconf -e virtual_transport=dovecot”
    . ok
    [….] Starting Postfix Mail Transport Agent: postfixpostmulti: fatal: /etc/postfix/main.cf, line 48: missing ‘=’ after attribute name: “postconf -e virtual_transport=dovecot”
    . ok
    —————————————–
    Also i do have
    tail -f /var/log/mail.log
    ………
    Nov 12 07:47:24 promitheus postfix/postmap[20734]: fatal: /etc/postfix/main.cf, line 45: missing ‘=’ after attribute name: “postconf -e virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf,mysql:/etc/postfix/mysql-email2email.cf”
    Nov 12 07:48:55 promitheus postfix/postmap[20736]: fatal: /etc/postfix/main.cf, line 45: missing ‘=’ after attribute name: “postconf -e virtual_alias_maps=mysql:/etc/postfix/mysql-virtual-alias-maps.cf”
    Nov 12 08:07:46 promitheus dovecot: master: Warning: Killed with signal 15 (by pid=20793 uid=0 code=kill)
    Nov 12 08:07:46 promitheus dovecot: master: Dovecot v2.1.7 starting up (core dumps disabled)
    Nov 12 08:23:19 promitheus postfix/master[21005]: fatal: bind 0.0.0.0 port 25: Address already in use

    i am stuck

    1. Christoph Haas

      I would say that you managed to put "postconf -e" into your main.cf. But "postconf -e" is a shell command to manipulate the main.cf. It is not supposed to be written into it.

  2. Hi Christoph,
    although it is not really a technical issue, the “previous chapter” link does not work 😉
    Viele Grüße,
    Andy

  3. Any idea how the dovecot line in /etc/postfix/master.cf needs to be modified in order to hand mail off to an imap server that isn’t running locally? I thought maybe changing the dovecot part to : and “unix” to “inet” might do the trick but postfix doesn’t like it…

    1. Gregor Messner

      You could do it with LMTP. But you need Dovecots LMTP on TCP socket instead of unix socket

      1. Can anybody share with examples how to setup postfix and devecot lmtp if postfix and dovecot is on separate hosts? and non-local storage for mailboxes?

        in postfix main.cf i have:
        smtpd_sasl_path = inet:dovecot.server.com:0000 (where 0000 is my port number)
        smtpd_sasl_type = dovecot ( i also want to authenticate with dovecot sasl, maybe should not…)
        smtp_sasle_type = dovecot
        lmtp_sasl_type = dovecot

        mailbox_transport = lmtp:inet:dovecot.server.com:0000
        virtual_transport = lmtp:inet:dovecot.server.com:0000

        but in dovecot master.cf

        service lmtp {
        inet listener {
        address = 127.0.0.1
        port = 0000
        }
        }

        service auth {
        inet_listener {
        port = 0000
        }
        }

        last one cause the error, cannot restart dovecot service.

        But i am not clear what i should setup and how exactly 🙁
        what listeners and service have to setup on dovecot? what for postfix transports, authentication, mail delivery…

        And how to setup mail delivery to non-local storage disk?
        Can any help with examples, explanations, suggestions?

        1. Where you able to figure this out? I am attempting to do the same thing and am not finding very good resources online.

  4. First of all thanks for this tutorial. Simply amazing…

    There is a provlem in this chapter. After following all the steps, I get
    “fatal: /etc/postfix/main.cf, line 46: missing ‘=’ after attribute name: “postconf -e virtual_transport=dovecot”

    I was somehow irritated when editing the main.cf this way, but I simply trusted thit tutorial, because it says:
    “.. by adding these lines to your /etc/postfix/main.cf:
    postconf -e virtual_transport=dovecot
    postconf -e dovecot_destination_recipient_limit=1”

    After deleting these line from the main.cf and executing the command from the shell everything works perfect….

    1. Christoph Haas

      Are you sure that you did not accidentally write "postconf -e virtual_transport=dovecot" into your main.cf instead of running that command in the shell? 🙂

      1. Yes, thtis is what I am saying. I DID write these two lines into the main.cf because this tutorial says so:
        “by adding these lines to your /etc/postfix/main.cf:
        postconf -e virtual_transport=dovecot
        postconf -e dovecot_destination_recipient_limit=1”

        After executing both commands from the shell, everything works fine. So you should clarify in the tutorial NOT to write these two lines into the main.cf but execute them from the shell.

    2. lightyellow

      oh,my god,Maybe you can multi-purpose use Google or Baidu. postconf -e is command for shell.you can add virtual_transport=dovecot in main.cf

  5. The apt-get install script for postfix automatically filled out the “mydestination = mydomain.ca, localhost.ca, localhost” section which caused the mail test to go through procmail locally.. setting it to “mydestination = ” cured this behavior

    1. Same problem here and your instruction cured it too, but doesn’t this cure incur that a virtual domain and users would have to be added in order for mails to be delivered to local accounts?

  6. Hi,

    after doing everything on this page and going on later (testing Dovecot) I had to run :
    postfix reload
    service postfix restart
    in order to get the new mail structure (/var/vmail/example.org/user/Maildir…)

  7. Hi,

    I see that a couple of other people have had the problem of: … missing “=” after attribute name …

    Did anybody figure it out? Which attribute is it referring to?

    The end of my main.cf file is:

    dovecot unix – n n – – pipe
    flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/dovecot-lda -f ${sender} -d ${recipient}
    virtual_transport = dovecot
    dovecot_destination_recipient_limit = 1

    (note: the second line beginning with “flags” is indented two spaces)

    And “postconf -e” is definitely not in the main.cf file. I realise it is a command to write to the file.

    Any clues greatly appreciated.

    Cheers

  8. Just adding to my last message. This is the error I get on restart.

    [….] Starting Postfix Mail Transport Agent: postfixpostmulti: fatal: /etc/postfix/main.cf, line 47: missing ‘=’ after attribute name: “dovecot unix – n n – – pipe flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/dovecot-lda -f ${sender} -d ${recipient}”
    . ok

  9. Do’h!

    I had written to main.cf in error.
    Once I wrote the first two lines to master.cf, and the last two lines to main.cf – all went well.

    When all else fails, read the instructions 🙂

  10. Don’t forget remove mydestination postfix setting and replace it with virtual_mailbox_domains = your_domain_here

  11. If i add the the line:

    dovecot unix – n n – – pipe
    flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/dovecot-lda -f ${sender} -d ${recipient}

    to the end of postfix master cf and i restart is produces an error:

    server1 postfix/postfix-script[1622]: fatal: cannot execute /usr/sbin/postconf!

    Anybody got an idea what this could be?

  12. Just to let you know your CMS has done something weird to the “-” in the line
    dovecot unix – n n – – pipe
    resulting in this in the log file
    fatal: /etc/postfix/master.cf: line 117: field “private”: bad value: “???”

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to Top