mikenye/postfix!Docker !Linting
Postfix is Wietse Venema's excellent mail server.
This container attempts to simplify and streamline setting up inbound and outbound mail relays, to protect and enhance self hosted email servers (eg: Microsoft Exchange). However, if you find an alternate use, please let me know so I can add to "Deployment Recipes".
The container employs Postfix's Postscreen for enhanced protection.
Apart from basic email relaying, the container can optionally:
The container is fully configured via environment variables - each service's configuration files built from environment variables on container start. It also supports some configuration files via volume mappings.
Currently supported docker architectures are linux/386, linux/amd64, linux/arm/v7 and linux/arm64.
Please note - docker hub cuts off this readme as it is quite long. To view the full readme click here.
This container implement's the excellent s6-overlay for process supervision (and a bunch of other handy stuff).
| Service Name | Description | When is it started |
|---|---|---|
postfix | Runs postfix | Always |
clamav-milter | Part of ClamAV. Runs the clamav-milter for scanning emails for virii. | If ENABLE_CLAMAV is set to true |
clamd | Part of ClamAV. Runs clamd, the virus scanning engine for clamav-milter. | If ENABLE_CLAMAV is set to true |
freshclam | Part of ClamAV. Runs freshclam on the schedule defined by FRESHCLAM_CHECKS_PER_DAY to keep the ClamAV database updated. | If ENABLE_CLAMAV is set to true |
opendkim | Runs opendkim for DKIM signing/verification. | If ENABLE_OPENDKIM is set to true |
postgrey | Runs postgrey for greylisting. | If ENABLE_POSTGREY is set to true |
postgrey_whitelist_update | Runs daily. Fetches the latest system whitelist from <[***]>, merges with any locally defined whitelist, and reloads postgrey. | If ENABLE_POSTGREY is set to true |
syslogd | Present for opendkim and postgrey logging. | Always |
!Wrapping an Exchange Server
In this deployment recipe, two containers (mail_in and mail_out) are created.
mail_in is designed to sit between the internet and a local legacy Exchange server. It handles inbound email, and provides the following:
postscreen to ensure the sending MTA is standards compliantmail_out is designed to sit between the local legacy Exchange server and the internet. It handles outbound email, and provides the following:
From a networking perspective:
mail_in on port TCP 2525.An example docker-compose.yml file is follows:
yamlversion: '3.8' volumes: queue_out: driver: local queue_in: driver: local certs: driver: local dkim: driver: local clamav_in: driver: local clamav_out: driver: local postgrey_in: driver: local tables_in: driver: local aliases_in: driver: local asupdata_in: driver: local logs_in: driver: local logs_out: driver: local services: mail_out: image: mikenye/postfix container_name: mail_out restart: always logging: driver: "json-file" options: max-file: "10" max-size: "10m" ports: - "25:25" environment: TZ: "Australia/Perth" POSTMASTER_*** "***" POSTFIX_INET_PROTOCOLS: "ipv4" POSTFIX_MYORIGIN: "mail.yourdomain.tld" POSTFIX_PROXY_INTERFACES: "your.external.IP.address" POSTFIX_MYNETWORKS: "your.local.LAN.subnet/prefix" POSTFIX_MYDOMAIN: "yourdomain.tld" POSTFIX_MYHOSTNAME: "mail.yourdomain.tld" POSTFIX_MAIL_NAME: "outbound" POSTFIX_SMTPD_TLS_CHAIN_FILES: "/etc/postfix/certs/privkey.pem, /etc/postfix/certs/fullchain.pem" POSTFIX_SMTP_TLS_CHAIN_FILES: "/etc/postfix/certs/privkey.pem, /etc/postfix/certs/fullchain.pem" POSTFIX_SMTPD_TLS_SECURITY_LEVEL: "may" POSTFIX_SMTPD_TLS_LOGLEVEL: 1 POSTFIX_REJECT_INVALID_HELO_HOSTNAME: "false" POSTFIX_REJECT_NON_FQDN_HELO_HOSTNAME: "false" POSTFIX_REJECT_UNKNOWN_HELO_HOSTNAME: "false" ENABLE_OPENDKIM: "true" OPENDKIM_SIGNINGTABLE: "/etc/mail/dkim/SigningTable" OPENDKIM_KEYTABLE: "/etc/mail/dkim/KeyTable" OPENDKIM_MODE: "s" OPENDKIM_INTERNALHOSTS: "your.local.LAN.subnet/prefix" OPENDKIM_LOGRESULTS: "true" OPENDKIM_LOGWHY: "true" ENABLE_CLAMAV: "true" CLAMAV_MILTER_REPORT_HOSTNAME: "mail.yourdomain.tld" volumes: - "certs:/etc/postfix/certs:ro" - "dkim:/etc/mail/dkim:rw" - "clamav_out:/var/lib/clamav:rw" - "queue_out:/var/spool/postfix:rw" - "logs_out:/var/log:rw" mail_in: image: mikenye/postfix container_name: mail_in restart: always logging: driver: "json-file" options: max-file: "10" max-size: "10m" dns: - 8.8.8.8 - 8.8.4.4 ports: - "2525:25" environment: TZ: "Australia/Perth" POSTMASTER_*** "***" POSTFIX_INET_PROTOCOLS: "ipv4" POSTFIX_MYORIGIN: "mail.yourdomain.tld" POSTFIX_PROXY_INTERFACES: "your.external.IP.address" POSTFIX_MYDOMAIN: "yourdomain.tld" POSTFIX_MYHOSTNAME: "mail.yourdomain.tld" POSTFIX_MAIL_NAME: "inbound" POSTFIX_SMTPD_TLS_CHAIN_FILES: "/etc/postfix/certs/privkey.pem, /etc/postfix/certs/fullchain.pem" POSTFIX_SMTP_TLS_CHAIN_FILES: "/etc/postfix/certs/privkey.pem, /etc/postfix/certs/fullchain.pem" POSTFIX_SMTPD_TLS_SECURITY_LEVEL: "may" POSTFIX_SMTPD_TLS_LOGLEVEL: 1 POSTFIX_RELAYHOST: "exchange.server.IP.addr" POSTFIX_RELAY_DOMAINS: "yourdomain.tld,someotherdomain.tld" POSTFIX_DNSBL_SITES: "hostkarma.junkemailfilter.com=127.0.0.2, bl.spamcop.net, cbl.abuseat.org=127.0.0.2, zen.spamhaus.org" ENABLE_OPENDKIM: "true" OPENDKIM_MODE: "v" OPENDKIM_LOGRESULTS: "true" OPENDKIM_LOGWHY: "true" ENABLE_SPF: "true" ENABLE_CLAMAV: "true" CLAMAV_MILTER_REPORT_HOSTNAME: "mail.yourdomain.tld" ENABLE_POSTGREY: "true" ENABLE_LDAP_RECIPIENT_ACCESS: "true" POSTFIX_LDAP_SERVERS: "active.directory.server.IP,active.directory.server.IP" POSTFIX_LDAP_BIND_DN: "CN=mailrelay,OU=Service Accounts,OU=Users,DC=yourdomain,DC=tld" POSTFIX_LDAP_BIND_PW: "***" POSTFIX_LDAP_SEARCH_BASE: "DC=yourdomain,DC=tld" volumes: - "certs:/etc/postfix/certs:ro" - "queue_in:/var/spool/postfix:rw" - "clamav_in:/var/lib/clamav:rw" - "postgrey_in:/etc/postgrey:ro" - "tables_in:/etc/postfix/tables:ro" - "aliases_in:/etc/postfix/local_aliases:ro" - "logs_in:/var/log:rw"
It is recommended to make your volume mounts somewhere you can access them, so you can edit files, load certificates, view logs easily, etc.
For example, you could map through to a known local path:
yamlvolumes: queue_out: driver: local type: 'none' o: 'bind' device: '/opt/mail/queue_out' ...
...or, another example useing NFS to a filer/server, eg:
yamlvolumes: queue_out: driver: local type: nfs o: addr=1.2.3.4,rw device: ":/vol/mail/queue_out" ...
| Environment Variable | Description |
|---|---|
ENABLE_CLAMAV | Optional. Set to "true" to enable ClamAV. Default is "false". |
ENABLE_LDAP_RECIPIENT_ACCESS | Optional. Enable LDAP-based recipient verification. See LDAP Recipient Verification section below. |
ENABLE_OPENDKIM | Optional. Set to "true" to enable OpenDKIM. If OpenDKIM is enabled, the "OpenDKIM Configuration" variables below will need to be set. Default is "false". |
ENABLE_POSTGREY | Optional. Set to "true" to enable postgrey. Default is "false". |
ENABLE_SPF | Optional. Set to "true" to enable policyd-spf. Default is "false". |
POSTMASTER_EMAIL | Required. Set to the email of your domain's postmaster. Example: ***. |
TZ | Recommended. Set the timezone for the container. Default is UTC. |
| Environment Variable | Description |
|---|---|
SYSLOG_PRIORITY | Optional. Log only messages more urgent than SYSLOG_PRIORITY. 0 = Emergency, 1 = Alert, 2 = Critical, 3 = Error, 4 = Warning, 5 = Notice, 6 = Info (the default), 7 = Debug |
| Environment Variable | Documentation Link |
|---|---|
POSTFIX_DNSBL_SITES | See documentation link. |
POSTFIX_DNSBL_THRESHOLD | See documentation link. |
POSTFIX_INET_PROTOCOLS | See documentation link. |
POSTFIX_MAIL_NAME | See documentation link. |
POSTFIX_MESSAGE_SIZE_LIMIT | See documentation link. |
POSTFIX_MYDOMAIN | See documentation link. |
POSTFIX_MYHOSTNAME | See documentation link. |
POSTFIX_MYNETWORKS | See documentation link. |
POSTFIX_MYORIGIN | See documentation link. |
POSTFIX_PROXY_INTERFACES | See documentation link. |
POSTFIX_REJECT_INVALID_HELO_HOSTNAME | See documentation link. |
POSTFIX_REJECT_NON_FQDN_HELO_HOSTNAME | See documentation link. |
POSTFIX_REJECT_UNKNOWN_HELO_HOSTNAME | See documentation link. |
POSTFIX_RELAY_DOMAINS | See documentation link. |
POSTFIX_RELAYHOST_PORT | Optional port argument for POSTFIX_RELAYHOST. Default is 25 so only need to change if you're relayhost is running on a different port. |
POSTFIX_RELAYHOST | See documentation link. |
POSTFIX_SMTP_TLS_CHAIN_FILES | See documentation link. |
POSTFIX_SMTPD_MILTERS | Any milters given here are applied after DKIM & ClamAV. See documentation link. |
POSTFIX_SMTPD_RECIPIENT_RESTRICTIONS_PERMIT_SASL_AUTHENTICATED | Set to true to include in smtpd_recipient_restrictions. See documentation link. |
POSTFIX_SMTPD_TLS_CERT_FILE | See documentation link. |
POSTFIX_SMTPD_TLS_CHAIN_FILES | See documentation link. |
POSTFIX_SMTPD_TLS_KEY_FILE | See documentation link. |
POSTFIX_SMTPD_TLS_LOGLEVEL | See documentation link. |
POSTFIX_SMTPD_TLS_SECURITY_LEVEL | See documentation link. |
POSTFIX_SMTPD_USE_TLS | See documentation link. |
POSTFIX_SMTPUTF8_ENABLE | See documentation link. |
POSTFIX_CHECK_RECIPIENT_ACCESS_FINAL_ACTION | If recipient checks are enabled (via ENABLE_LDAP_RECIPIENT_ACCESS and/or recipient_access.hash), this is the final action taken after all other checks. Default is defer. Usually should be set to either defer or reject. See documentation link. |
See "LDAP" section below.
If ENABLE_LDAP_RECIPIENT_ACCESS is enabled, the final smtpd_recipient_restrictions action becomes defer (from the default of permit).
| Environment Variable | Documentation Link |
|---|---|
POSTFIX_LDAP_SERVERS | Required. Comma separated list of LDAP servers. |
POSTFIX_LDAP_VERSION | Optional. LDAP version. Default is 3 (which works with Active Directory). |
POSTFIX_LDAP_QUERY_FILTER | Optional. LDAP query filter to find user/group emails. Default is `(&( |
POSTFIX_LDAP_SEARCH_BASE | Required. The base DN in which to search for users/groups. eg: DC=MyDomain,DC=tld. |
POSTFIX_LDAP_BIND_DN | Required. The account name to use to bind to the LDAP servers, specified in LDAP syntax, eg: CN=svc-mailrelay,OU=Service Accounts,OU=Users,DC=MyDomain,DC=tld. |
POSTFIX_LDAP_BIND_PW | Required. The account password for the POSTFIX_LDAP_BIND_DN account. |
POSTFIX_LDAP_DEBUG_LEVEL | Optional. If you're having problems, you can set this to 1 or higher. |
| Environment Variable | Detail |
|---|---|
OPENDKIM_DOMAIN | Comma separated list of domains whose mail should be signed by this filter. |
OPENDKIM_INTERNALHOSTS | Comma separated list of internal hosts whose mail should be signed rather than verified. |
OPENDKIM_KEYFILE | Gives the location (within the container) of a PEM-formatted private key to be used for signing all messages. |
OPENDKIM_KEYTABLE | Path to a key table. You do not need to include refile:. Can be used instead of OPENDKIM_KEYFILE & OPENDKIM_SELECTOR for multiple domains. |
OPENDKIM_LOGRESULTS | Set to true for for logging of the results of evaluation of all signatures that were at least partly intact. |
OPENDKIM_LOGWHY | Set to true for very detailed logging about the logic behind the filter’s decision to either sign a message or verify it. |
OPENDKIM_MODE | Selects operating modes. The string is a concatenation of characters that indicate which mode(s) of operation are desired. Valid modes are s (signer) and v (verifier). The default is sv except in test mode (see the opendkim(8) man page) in which case the default is v. When signing mode is enabled, one of the following combinations must also be set: (a) Domain, KeyFile, Selector, no KeyTable, no SigningTable; (b) KeyTable, SigningTable, no Domain, no KeyFile, no Selector; (c) KeyTable, SetupPolicyScript, no Domain, no KeyFile, no Selector. |
OPENDKIM_SELECTOR | Set to the selector specified when creating the Key File. |
OPENDKIM_SIGNINGTABLE | Path to a signing table file. You do not need to include refile:. Can be used instead of OPENDKIM_DOMAIN for multiple domains. |
OPENDKIM_SUBDOMAINS | Set to true to sign subdomains of those listed by the Domain parameter as well as the actual domains. |
| Environment Variable | Detail |
|---|---|
FRESHCLAM_CHECKS_PER_DAY | Optional. Number of database checks per day. Default: 12 (every two hours). |
CLAMAV_MILTER_REPORT_HOSTNAME | Optional. The hostname ClamAV Milter will report in the X-Virus-Scanned header. If unset, defaults to the container's hostname. |
CLAMAV_CLAMD_PHISHING_SIGNATURES | Optional. Overrides ClamAV Daemon's default setting for PhishingSignatures. |
CLAMAV_CLAMD_PHISHING_SCAN_URLS | Optional. Overrides ClamAV Daemon's default setting for PhishingScanURLs. |
CLAMAV_CLAMD_PHISHING_ALWAYS_BLOCK_SSL_MISMATCH | Optional. Overrides ClamAV Daemon's default setting for PhishingAlwaysBlockSSLMismatch. |
CLAMAV_CLAMD_PHISHING_ALWAYS_BLOCK_CLOAK | Optional. Overrides ClamAV Daemon's default setting for PhishingAlwaysBlockCloak. |
CLAMAV_CLAMD_HEURISTIC_SCAN_PRECEDENCE | Optional. Overrides ClamAV Daemon's default setting for HeuristicScanPrecedence. |
The following files can be optionally configured.
If using postfix table files, it is recommened to place all files into a single directory, and map this directory through to the container at /etc/postfix/tables.
| Table File (with respect to container) | Format | If this file is present... | After modifying... |
|---|---|---|---|
/etc/postfix/tables/body_checks.pcre | pcre | It is automatically added to postfix's 'body_checks'. | Run helper command update_body_checks (see below) |
/etc/postfix/tables/client_access.cidr | cidr | It is automatically added to postfix's check_client_access. | Run helper command update_client_access (see below) |
/etc/postfix/tables/dnsbl_reply.texthash | texthash | It is automatically added to postfix's postscreen_dnsbl_reply_map. | Run helper command update_dnsbl_reply (see below) |
/etc/postfix/tables/header_checks.pcre | pcre | It is automatically added to postfix's header_checks. | Run helper command update_header_checks (see below) |
/etc/postfix/tables/helo_access.hash | hash | It is automatically added to postfix's check_helo_access. | Run helper command update_helo_access (see below) |
/etc/postfix/tables/milter_header_checks.pcre | pcre | It is automatically added to postfix's milter_header_checks. | Run helper command update_milter_header_checks (see below) |
/etc/postfix/tables/postscreen_access.cidr | cidr | It is automatically added to postfix's 'postscreen_access_list' (after permit_mynetworks). | Run helper command update_postscreen_access (see below) |
/etc/postfix/tables/recipient_access.hash | hash | It is automatically added to postfix's check_recipient_access, and the final smtpd_recipient_restrictions action becomes defer (from the default of permit). | Run helper command check_recipient_access (see below) |
/etc/postfix/tables/sender_access.hash | hash | It is automatically added to postfix's check_sender_access. | Run helper command update_sender_access (see below) |
For the format of this file, see the postgrey manpage.
| Configuration file (with respect to container) | If this file is present... | After modifying... |
|---|---|---|
/etc/postgrey/postgrey_whitelist_clients.local | It is merged with the regularly updated system whitelist. | Run helper command update_postgrey_whitelist (see below). |
The system whitelist is downloaded from <[***]> once every 24 hours if postgrey is enabled.
The format of this file is as-per the /etc/aliases file.
| Configuration file (with respect to container) | If this file is present... | After modifying... |
|---|---|---|
/etc/postfix/local_aliases/aliases | It is merged with the system aliases file. | Run helper command update_aliases (see below). |
The system aliases file maps postmaster, root, postfix and clamav through to the address specified by POSTMASTER_EMAIL.
| Path | Access | Detail |
|---|---|---|
/var/spool/postfix | rw | Required. Mail queue & postgrey database. |
| Path | Access | Detail |
|---|---|---|
/var/lib/clamav | rw | ClamAV anti-virus database. Map if using ClamAV. |
/etc/postfix/local_aliases | rw | A file named aliases can be placed in this folder. The contents of this file will be added to the container's /etc/aliases at startup. Map if |
探索更多轩辕镜像的使用方法,找到最适合您系统的配置方式
通过 Docker 登录认证访问私有仓库
在 Linux 系统配置镜像服务
在 Docker Desktop 配置镜像
Docker Compose 项目配置
Kubernetes 集群配置 Containerd
K3s 轻量级 Kubernetes 镜像加速
VS Code Dev Containers 配置
MacOS OrbStack 容器配置
在宝塔面板一键配置镜像
Synology 群晖 NAS 配置
飞牛 fnOS 系统配置镜像
极空间 NAS 系统配置服务
爱快 iKuai 路由系统配置
绿联 NAS 系统配置镜像
QNAP 威联通 NAS 配置
Podman 容器引擎配置
HPC 科学计算容器配置
ghcr、Quay、nvcr 等镜像仓库
无需登录使用专属域名
需要其他帮助?请查看我们的 常见问题Docker 镜像访问常见问题解答 或 提交工单
免费版仅支持 Docker Hub 访问,不承诺可用性和速度;专业版支持更多镜像源,保证可用性和稳定速度,提供优先客服响应。
专业版支持 docker.io、gcr.io、ghcr.io、registry.k8s.io、nvcr.io、quay.io、mcr.microsoft.com、docker.elastic.co 等;免费版仅支持 docker.io。
当返回 402 Payment Required 错误时,表示流量已耗尽,需要充值流量包以恢复服务。
通常由 Docker 版本过低导致,需要升级到 20.x 或更高版本以支持 V2 协议。
先检查 Docker 版本,版本过低则升级;版本正常则验证镜像信息是否正确。
使用 docker tag 命令为镜像打上新标签,去掉域名前缀,使镜像名称更简洁。
来自真实用户的反馈,见证轩辕镜像的优质服务