Configuring Alpine Linux on Docker to Send Mail for WordPress

I got WordPress working, but the email wasn’t working. Nothing was going out from the blog application, but other mail in the system worked fine. The fix is to alter the sendmail configuration in php.ini.

Alpine Linux is a lean Linux, and doesn’t come with a complete sendmail. Rather, it uses BusyBox’s sendmail that forward email to an SMTP server. This is usually enough for most systems, but the problem arises because there’s no config file to change the SMTP server.

Most bloggers are suggesting installing ssmtp. While that works, you can also just reconfigure sendmail in the php.ini file.

FROM alpine:3.9

EXPOSE 80 443

VOLUME ["/opt/docker/apache/"]
# directory contains www/, config/, sites-enabled/

COPY docker-httpd.conf /etc/apache2/conf.d/docker-httpd.conf

RUN rm -f /var/www/localhost/htdocs/index.html
COPY index.php /var/www/localhost/htdocs/

RUN apk update && apk upgrade && \
    apk add --no-cache \
    apache2 \
    # apache2-http2 \
    # apache-mod-fcgid \
    # php7-fpm \
    php7-apache2 \
    php7-pdo \
    php7-gd php7-pdo_mysql php7-curl php7-mysqli \
    php7-iconv php7-json php7-xml php7-openssl \
    php7-sockets php7-ftp php7-session \
    php7-xml php7-ctype php7-dom php7-tokenizer

RUN apk add procps
RUN apk add php7-mbstring

RUN addgroup -g 2001 -S dapache
RUN adduser -S -D -H -u 2001 -G dapache dapache

COPY httpd.conf /etc/apache2/httpd.conf
COPY php.ini /etc/php7/php.ini

ENTRYPOINT ["/usr/sbin/httpd", "-D", "FOREGROUND"]

The php.ini is the default php.ini, with one change:

sendmail_path = /usr/sbin/sendmail -S 172.16.239.1 -t -i

The -S option specifies a relay server. The IP address 172.16.219.1 is an internal mail relay network, and it’s running a container with Postfix.

Set that value to your SMTP server. The sendmail command also supports options for authentication.

BusyBox v1.29.3 (2019-01-24 07:45:07 UTC) multi-call binary.

Usage: sendmail [-tv] [-f SENDER] [-amLOGIN 4<user_pass.txt | -auUSER -apPASS]
                [-w SECS] [-H 'PROG ARGS' | -S HOST] [RECIPIENT_EMAIL]...

Read email from stdin and send it

Standard options:
        -t              Read additional recipients from message body
        -f SENDER       For use in MAIL FROM:<sender>. Can be empty string
                        Default: -auUSER, or username of current UID
        -o OPTIONS      Various options. -oi implied, others are ignored
        -i              -oi synonym, implied and ignored

Busybox specific options:
        -v              Verbose
        -w SECS         Network timeout
        -H 'PROG ARGS'  Run connection helper. Examples:
                openssl s_client -quiet -tls1 -starttls smtp -connect smtp.gmail.com:25
                openssl s_client -quiet -tls1 -connect smtp.gmail.com:465
                        $SMTP_ANTISPAM_DELAY: seconds to wait after helper connect
        -S HOST[:PORT]  Server (default $SMTPHOST or 127.0.0.1)
        -amLOGIN        Log in using AUTH LOGIN (-amCRAM-MD5 not supported)
        -auUSER         Username for AUTH
        -apPASS         Password for AUTH

If no -a options are given, authentication is not done.
If -amLOGIN is given but no -au/-ap, user/password is read from fd #4.
Other options are silently ignored; -oi is implied.
Use makemime to create emails with attachments.

To test your configuration, I like to use the code from php.net:

<?php

$to      = 'youremailaddress@example.com';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: www-data@slaptech.net' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers);

Save that to a script, and run it. If you receive a mail, the configuration worked.