dpkg-reconfigure: dialog frontend sets up postfix successfully; non-interactive frontend fails

(N.B. In this question, a leading # indicates a root prompt, not a comment. Also, I have replaced the actual hostname with <myhostname>.)

As the debconf (7) man-page states, dpkg-reconfigure can be invoked with any one of several front-ends, including the default ("dialog") interactive front-end, and the "noninteractive" frontend.

Am I right in thinking that running

# dpkg-reconfigure postfix

to invoke the dialog front-end, and pressing Enter in response to each question, should be equivalent to running the following?

# dpkg-reconfigure -f noninteractive postfix

If so, then I do not understand the following discrepancy.

Discrepancy

On a VPS freshly-populated with Debian 9 "Stretch" from my web host's image (which has postfix already installed), I preseed using debconf-set-selections:

# debconf-set-selections <<< "postfix postfix/destinations string <myhostname>"
# debconf-set-selections <<< "postfix postfix/mailbox_limit string 51200000"              
# debconf-set-selections <<< "postfix postfix/mailname string <myhostname>"    
# debconf-set-selections <<< "postfix postfix/main_mailer_type select Internet Site"      
# debconf-set-selections <<< "postfix postfix/protocols select ipv4"                      
# debconf-set-selections <<< "postfix postfix/root_address string root"                   

If I then run dpkg-reconfigure interactively, and press Enter for every question, I get:

# dpkg-reconfigure postfix
dpkg-reconfigure postfix
Removing sqlite map entry from /etc/postfix/dynamicmaps.cf
setting synchronous mail queue updates: false
Adding sqlite map entry to /etc/postfix/dynamicmaps.cf
changing /etc/mailname to <myhostname>
setting myorigin
setting destinations: localhost
setting relayhost: 
setting mynetworks: 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
setting mailbox_size_limit: 51200000
setting recipient_delimiter: +
setting inet_interfaces: all
setting default_transport: smtp
setting relay_transport: smtp
setting inet_protocols: ipv4
WARNING: /etc/aliases exists, but does not have a root alias.

Postfix (main.cf) is now set up with the changes above.  If you need to make 
changes, edit /etc/postfix/main.cf (and others) as needed.  To view Postfix 
configuration values, see postconf(1).

After modifying main.cf, be sure to run 'service postfix reload'.

Running newaliases

Note that this does quite a lot, including setting /etc/mailname. At this point, postfix is ready to send mail.

By contrast, if I use the same VPS, starting again from a fresh image, and run the same commands except for invoking dpkg-reconfigure non-interactively, I get:

# dpkg-reconfigure --frontend noninteractive postfix
Removing sqlite map entry from /etc/postfix/dynamicmaps.cf
Adding sqlite map entry to /etc/postfix/dynamicmaps.cf

Postfix (main.cf) configuration was not changed.  If you need to make changes, 
edit /etc/postfix/main.cf (and others) as needed.  To view Postfix 
configuration values, see postconf(1).

After modifying main.cf, be sure to run 'service postfix reload'.

Running newaliases

Note that this time, /etc/mailname was not set. Moreover, at this point, postfix is not ready to send mail and any attempts to make it do so result in bounces showing up in /var/log/mail.log.

My questions

  1. Was my initial assumption correct?
  2. Is the above discrepancy a bug, or is it expected behaviour? (And if it is expected behaviour, then what was the rationale for this design choice?)

Addendum

If I run rm /etc/postfix/main.cf before running dpkg-reconfigure --frontend noninteractive postfix, then /etc/mailname and /etc/postfix/main.cf both end up being created, and postfix ends up ready to send mail. This seems to be a viable workaround for the above failure, but it certainly violates the Rule of Least Surprise and feels as though it might be undefined behaviour that should not be relied upon.


The postfix config files including /etc/mailname CANNOT be changed using debconf-set-selections and dpkg-reconfigure once the postfix config files have been written out. I burnt way too many hours trying to find out why...

Why?

dpkg-reconfigure -f noninteractive returns value 30 question skipped for all questions (and uses the debconf-set-selections presets), the code in /var/lib/dpkg/info/postfix.config then does not set the debconf settings as changed and /var/lib/dpkg/info/postfix.postinst then does not write any postfix config.

Workarounds?

  1. Good: The workaround as you found is to remove /etc/postfix/main.cf which forces /var/lib/dpkg/info/postfix.postinst to write out a new config for postfix which will include the new debconf-set-selections options.

  2. Better: Alternative use dpkg-reconfigure in an interactive mode and confirm the questions, in which case /var/lib/dpkg/info/postfix.config marks the options as changed and /var/lib/dpkg/info/postfix.postinst writes out the changes.

  3. Best: Alternative switch to managing /etc/postfix/main.cf etc options using postconf. (Likely a good idea to have a echo "postfix postfix/main_mailer_type select No configuration" | debconf-set-selections safety net)