MMaannaaggiinngg mmuullttiippllee PPoossttffiixx iinnssttaanncceess oonn aa ssiinnggllee hhoosstt
-------------------------------------------------------------------------------
OOvveerrvviieeww
This document is a guide to managing multiple Postfix instances on a single
host using the postmulti(1) instance manager. Multi-instance support is
available with Postfix version 2.6 and later. See the postfix-wrapper(5) manual
page for background on the instance management framework, and on how to deploy
a custom instance manager.
Topics covered in this document:
* Why multiple Postfix instances
* Null-client instances versus service instances
* Multi-instance walk-through
* Components of a Postfix system
* The default Postfix instance
* Instance groups
* Multi-instance configuration parameters
* Using the postmulti(1) command
* Credits
WWhhyy mmuullttiippllee PPoossttffiixx iinnssttaanncceess
Postfix is a general-purpose mail system that can be configured to serve a
variety of needs. Examples of Postfix applications are:
* Local mail submission for shell users and system processes.
* Incoming (MX host) email from the Internet.
* Outbound mail relay for a corporate network.
* Authenticated submission for roaming users.
* Before/after content-filter mail.
A single Postfix configuration can provide many or all of these services, but a
complex interplay of settings may be required, for example with master.cf
options overriding main.cf settings. In this document we take the view that
multiple Postfix instances may be a simpler way to configure a multi-function
Postfix system. With multiple Postfix instances, each instance has its own
directories for configuration, queue and data files, but it shares all Postfix
program and documentation files with other instances.
Since there is no single right way to configure your system, we recommend that
you choose what makes you most comfortable. If different Postfix services don't
involve incompatible main.cf or master.cf settings, and if they can be combined
together without complex tricks, then a single monolithic configuration may be
the simplest approach.
The purpose of multi-instance support in Postfix is not to force you to create
multiple Postfix instances, but rather to give you a choice. Multiple instances
give you the freedom to tune each Postfix instance to a single task that it
does well and to combine instances into complete systems.
With the introduction of the postmulti(1) utility and the reduction of the per-
instance configuration footprint of a secondary Postfix instance to just a
main.cf and master.cf file (other files are now in shared locations), we hope
that multiple instances will be easier to use than ever before.
NNuullll--cclliieenntt iinnssttaanncceess vveerrssuuss sseerrvviiccee iinnssttaanncceess
In the multi-instance approach to configuring Postfix, the first simplification
is with the default local-submission Postfix instance.
Most UNIX systems require support for email submission with the sendmail(1)
command so that system processes such as cron jobs can send status reports, and
so that system users can send email with command-line utilities. Such email can
be handled with a null-client Postfix configuration that forwards all mail to a
central mail hub. The null client will typically either not run an SMTP
listener at all (master_service_disable = inet), or it will listen only on the
loopback interface (inet_interfaces = loopback-only).
When implementing specialized servers for inbound Internet email, outbound
MTAs, internal mail hubs, and so on, we recommend using a null client for local
submission and creating single-function secondary Postfix instances to serve
the specialized needs.
Note: usually, you need to use different "myhostname" settings when you run
multiple instances on the same host. Otherwise, there will be false "mail
loops back to myself" alarms when one instance tries to send mail into
another instance. Typically, the null-client instance will use the system's
hostname, and other instances will use their own dedicated "myhostname"
settings. Different names are not needed when instances send mail to each
other with a protocol other than SMTP, or with SMTP over a TCP port other
than 25 as is usual with SMTP-based content filters.
MMuullttii--iinnssttaannccee wwaallkk--tthhrroouugghh
Before discussing the fine details of multi-instance operation we first show
the steps for creating a border mail server. This server has with a null-client
Postfix instance for local submission, an input Postfix instance to receive
mail from the Internet, plus an advanced SMTP content-filter and an output
Postfix instance to deliver filtered email to its internal destination.
SSeettttiinngg uupp tthhee nnuullll--cclliieenntt PPoossttffiixx iinnssttaannccee
On a border mail hub, while mail from the Internet requires a great deal of
scrutiny, locally submitted messages are typically limited to mail from cron
jobs and other system services. In this regard the border MTA is not different
from other Unix hosts in your environment. For this reason, it will submit
locally-generated email to the internal mail hub. We start the construction of
the border mail server with the default instance, which will be a local-
submission null client:
/etc/postfix/main.cf:
# We are mta1.example.com
#
myhostname = mta1.example.com
mydomain = example.com
# Flat user-account namespace in example.com:
#
# user@example.com not user@host.example.com
#
myorigin = $mydomain
# Postfix 2.6+, disable inet services, specifically disable smtpd(8)
#
master_service_disable = inet
# No local delivery:
#
mydestination =
local_transport = error:5.1.1 Mailbox unavailable
alias_database =
alias_maps =
local_recipient_maps =
# Send everything to the internal mailhub
#
relayhost = [mailhub.example.com]
# Indexed table macro:
# (use "hash", ... when cdb is not available)
#
default_database_type = cdb
indexed = ${default_database_type}:${config_directory}/
# Expose origin host of mail from "root", ...
#
smtp_generic_maps = ${indexed}generic
# Send messages addressed to "root", ... to the MTA support team
#
virtual_alias_maps = ${indexed}virtual
/etc/postfix/generic:
# The smarthost supports "+" addressing (recipient_delimiter = +).
# Mail from "root" exposes the origin host, without replies
# and bounces going back to the same host.
#
# On clustered MTAs this file is typically machine-built from
# a template file. The build process expands the template into
# "mtaadmin+root=mta1"
#
root mtaadmin+root=mta1
/etc/postfix/virtual:
# Caretaker aliases:
#
root mtaadmin
postmaster root
You would typically also add a Makefile, to automatically run postmap(1)
commands when source files change. This Makefile also creates a "generic"
database when none exists.
/etc/postfix/Makefile:
MTAADMIN=mtaadmin
all: virtual.cdb generic.cdb
generic: Makefile
@echo Creating $@
@rm -f $@.tmp
@printf '%s\t%s+root=%s\n' root $MTAADMIN `uname -n` > $@.tmp
@mv $@.tmp generic
%.cdb: %
postmap cdb:$<
Construct the "virtual" and "generic" databases (the latter is created by
running "make"), then start and test the null-client:
# cd /etc/postfix; make
# postfix start
# sendmail -i -f root -t <