persistent postfix config inside PHP docker container
One of my recent tasks included migrating an internal PHP-FPM application from a Debian 9 host (with a global PHP 7.0 installation) to a more flexible docker setup. One of the requirements was to retain the ability for the app to send mails to it’s users, which meant having a local SMTP server directly accessible to the PHP docker instance, and relaying any mails to a server on the outside.
I decided to set up a dockerized PHP-FPM environment through PHP’s official docker repo using their image tagged as php:7.4-fpm-buster.
After some trial and error regarding proper RUN commands in the Dockerfile, this is what I came up with, which allows for a persistent mail server setup inside the PHP-FPM container.
FROM php:7.4-fpm-buster ENV TZ="Europe/Berlin" RUN echo "date.timezone = Europe/Berlin" > /usr/local/etc/php/conf.d/timezone.ini RUN date RUN echo "postfix postfix/mailname string internalapp.example.com" | debconf-set-selections RUN echo "postfix postfix/main_mailer_type string 'Internet Site'" | debconf-set-selections RUN apt-get update && apt-get install -y postfix libldap2-dev libbz2-dev \ && docker-php-ext-install bcmath ldap bz2 RUN postconf -e "myhostname = internalapp.example.com" RUN postconf -e "relayhost = 172.18.0.1" ADD launch.sh /launch.sh CMD ["/launch.sh"]
Content of launch.sh:
#!/bin/bash -e /etc/init.d/postfix start php-fpm
The extra launch script functions as a wrapper to execute postfix and php-fpm with the same CMD command.
Of course, “internalapp.example.com” is just a placeholder for the actual service URL. It’s important to set the postfix variables early through debconf-set-selections to allow for a promptless postfix installation later on, otherwise the container deployment gets stuck. I’ve also had to manually set the time zone, confirming it’s correctness by visually echoing date during deployment.
The relayhost is just the docker host itself, which is - in this case - running a postfix as well. Since I want it to act as a relay for my dockerized app, I’ve had to edit /etc/postfix/main.cf, allowing for relay access to it from my docker network (which has been explicitly persisted in it’s docker-compose.yml):
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 172.18.0.0/24
One advantage of using the host mail server as a relay is everything gets logged in it’s local mail.log, which might be helpful for further debugging or auditing.