Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Email does not work #30

Open
md5 opened this issue Nov 17, 2014 · 68 comments

Comments

Projects
None yet
@md5
Copy link
Contributor

commented Nov 17, 2014

As it currently stands, anything in Wordpress that needs to send email is broken. The wp_mail function that is used for sending out email by default is a thin wrapper over PHP's mail function, which defaults to calling /usr/sbin/sendmail -t -i (cf. http://php.net/manual/en/mail.configuration.php). There are php.ini settings for SMTP, but they are only used on Windows.

For my own work based on this image, I've been installing ssmtp and configuring it to use an external relay host for SMTP, but that's clearly not a turnkey solution for everyone. It also looks like there are many Wordpress plugins that provide SMTP support, but I don't think that installing any of them by default in this image seems reasonable.

Perhaps all of this should just be documented, but I wanted to get it on your radar.

@md5 md5 changed the title Broken wp_mail Email does not work Nov 17, 2014

@tianon

This comment has been minimized.

Copy link
Member

commented Nov 17, 2014

Yeah... This was a hole we've had on our radar for a long time now, but
didn't have a good solution. Perhaps an actual issue will get some
brainshare going. We thought about something like ssmtp, but there really
is no good solution that'll work for 90% of users out of the box. Email
is hard. :(

@md5

This comment has been minimized.

Copy link
Contributor Author

commented Nov 17, 2014

It looks like WP actually uses something called PHPMailer under the hood, which does support SMTP, but it requires a custom hook for configuration: http://codex.wordpress.org/Plugin_API/Action_Reference/phpmailer_init#Examples

@omarabid

This comment has been minimized.

Copy link

commented Jan 2, 2015

@md5 An alternative is to use a service like mailchimp and Mandrill. I know these are paying services, and not on your own service but the good thing (for Mandrill) is that you can opt out at any moment.

My experience is, your server emails will be probably put in SPAM folder. This is not the case for Mandrill.

@md5

This comment has been minimized.

Copy link
Contributor Author

commented Jan 2, 2015

@omarabid using Mailchimp or Mandrill still requires using SMTP, which isn't supported out of the box by Wordpress under Linux. As I mentioned in an earlier comment, it would be possible to add one of the WP plugins that supports SMTP, but I don't think it would be reasonable for a generic Wordpress image to include specific plugins.

In my case, I was using ssmtp to connect to Google Apps with a dedicated mail user. This will avoid spam issues just as well as Mandrill. The case you're talking about is likely the default scenario of a PHP app using the local /usr/sbin/sendmail to send its mail out with no relay host settings. In that case, assuming the IP either isn't listed in the domain's SPF records or the IP is part of a spammy netblock, you will indeed have deliverability problems.

@omarabid

This comment has been minimized.

Copy link

commented Jan 3, 2015

using Mailchimp or Mandrill still requires using SMTP

No, otherwise, what's the point of using Mandrill.

@md5

This comment has been minimized.

Copy link
Contributor Author

commented Jan 3, 2015

Ok, you're right that you can use Mandrill with their REST API instead of SMTP, but that requires installing this plugin or some other plugin that knows how to use that API.

As for the point of using Mandrill with SMTP, there are a ton of reasons you might want to do that, including open tracking, click tracking, deliverability concerns, email volume, etc. Not of those advantages of the Mandrill service rely on using the REST API.

@omarabid

This comment has been minimized.

Copy link

commented Jan 3, 2015

@md5 I was just suggesting a solution. Obviously, this should be available/fixed for the official Docker repo.

@booyaa

This comment has been minimized.

Copy link

commented Apr 21, 2015

Wondering how modular you can make the smtp solution> A nice implementation that I've seen is this one https://github.com/catatnight/docker-postfix , but it does bolt on TLS and and OpenDKIM. Perhaps it could be paired down to just postfix? I'm assuming it would only be used via container link so you don't need TLS. DKIM is fall back to avoid DNS shenanigans, admittedly not having it or SSP will probably cause some filters to flag you as spammy.

Thoughts? I think it's time to retreat to the lab 😀

@timwsuqld

This comment has been minimized.

Copy link

commented Apr 21, 2015

We are using SSMTP to relay to our main mailserver.
We have a php sendmail.ini file that contains the single line:

sendmail_path = /usr/sbin/ssmtp -t

We have a sed in the Dockerfile that changes the mailhub, rewritedomain and removes the hostname line from the ssmtp file (this way it gets the container id as the hostname)

RUN sed -i -e 's/mailhub=mail/mailhub=ourmailrelay.domain/' \
    -e 's/#rewriteDomain=/rewriteDomain=ourdomain/' \
    -e '/hostname=/d' \
    /etc/ssmtp/ssmtp.conf

This works really well, and as ssmtp isn't a daemon, it doesn't require any process management

@md5

This comment has been minimized.

Copy link
Contributor Author

commented Apr 21, 2015

@booyaa I don't like that the Postfix container you mention is using supervisord and running its own rsyslog, but that's a moot point probably.

I think the real issue is that PHP is still going to expect a working sendmail-compatible command which will need to be configured to talk to the linked SMTP container (whether it's postfix or some other SMTP server). Getting such a setup working and maintaining it would be error prone.

I still think the best that can be done here without assuming too much is simply to document the options.

@booyaa

This comment has been minimized.

Copy link

commented Apr 22, 2015

Random musing: this problem would be a great candidate for a mail service docker-compose.yml firing up smtp, imap, spam assassin, clamav and webmail

@md5

This comment has been minimized.

Copy link
Contributor Author

commented Apr 22, 2015

@booyaa 👍

@pierreozoux

This comment has been minimized.

Copy link

commented Jun 27, 2015

One good option is to configure SSMTP with ENV variables.
This way, you could put your GMAIL or Mandrill cred, and it would work out of the box!

@kcmerrill

This comment has been minimized.

Copy link

commented Jul 25, 2015

If this is an old post, or there has previously been a resolution please disregard.

One quick way of getting mail working inside the container is to install msmtp.

Then, in a configuration file(example: msmtp):

account default
host 172.17.42.1
auto_from on

Copy this to /etc/ inside the container

Update the php.ini or set the sendmail_path variable like so:

sendmail_path = "/usr/bin/msmtp -t -i"

TL;DR
Use msmtp to point to the guest machine or some other container.

@omarabid

This comment has been minimized.

Copy link

commented Jul 28, 2015

@md5 Any updates on this? I like the new container for SMTP approach. It separates concerns. However, this seems like a WordPress issue for me.

@md5

This comment has been minimized.

Copy link
Contributor Author

commented Jul 28, 2015

@omarabid I'm not aware of any developments on this issue other than what you can read in this thread.

@robertoandrade

This comment has been minimized.

Copy link

commented Aug 26, 2015

Perhaps since a bunch of you have been able to successfully run ssmtp in the container alongside Wordpress, I thought I'd pose the question here. My install, even after properly configuring /etc/ssmtp/ssmtp.conf with the main SMTP server to relay to still errors out.

Via a simple mail() function test it fails, via wp_mail as well. When I try sendmail from the command line (inside the container) it locks after sending the last <CR>.<CR> and after a timeout period errors with sendmail: Cannot open server-address:port, which matches what I have in the .conf file. I'm using SSL on the other endpoint so wondering if that could play any part in the issue.

@md5

This comment has been minimized.

Copy link
Contributor Author

commented Aug 26, 2015

Have you tried telnet server-address port to see if that hangs as well?

Try something like this:

$ docker run -t --rm debian:jessie 'apt-get update && apt-get install -y telnet && telnet server-address port'

If that hangs too, then the problem is probably being caused by firewall rules on the host (outside the container). This can happen if the server you're trying to contact is on an RFC 1918 private subnet like something under 192.168.0.0/16 and your host thinks it should drop packets from the Docker bridge network.

@robertoandrade

This comment has been minimized.

Copy link

commented Aug 26, 2015

Yeah, did it, and it works fine. it responds. so don't think it's networking related.

Anyways ended up ditching ssmtp completely on the container and just configured WordPress to use the external mailer directly via a plugin that intercepts the calls to mail(): http://coffee2code.com/wp-plugins/configure-smtp/

@md5

This comment has been minimized.

Copy link
Contributor Author

commented Aug 26, 2015

That's odd. I haven't seen sendmail time out for reasons other than packet drops, but perhaps the SMTP server was overloaded or something?

It would be good to get to the bottom of the issue if only for the sake of other users who hit problems using ssmtp.

BTW, I should point out that sendmail inside the container will be a symlink to ssmtp if that's all you have installed.

@pierreozoux

This comment has been minimized.

Copy link

commented Oct 2, 2015

Ok, just to continue the discussion, here is a working example with ssmtp configured with env variables:

https://github.com/indiehosters/wordpress/

@nathan-osman

This comment has been minimized.

Copy link

commented Oct 4, 2015

So I've managed to come up with a solution that involves another container and a WordPress plugin. The container is running an SMTP client that I wrote (named Hectane) and the WordPress plugin routes all calls to wp_mail() through the container.

Here are the commands to get it up and running:

docker run -d --name db mysql:latest
docker run -d --name mail hectane/hectane:0.2.1
docker run \
    -d -P \
    --link db:db \
    --link mail:mail \
    wordpress:latest

Once the containers are up and running, it's simply a matter of installing and activating this WordPress plugin and changing the hostname to "mail" in "Settings".

WordPress Configuration

Once that's done, all emails will be sent through Hectane and delivered via SMTP.

@joao-parana

This comment has been minimized.

Copy link

commented Nov 15, 2015

Hi @nathan-osman, is it possible use hectane/hectane container with Drupal 8 ?

@ahansson89

This comment has been minimized.

Copy link

commented Dec 17, 2015

I am using SendGrid for emails. It is super easy to set up with one of the many WP plugins and then you will send emails through an API while getting insights on open rate, bounce rate etc.

@geekscrapy

This comment has been minimized.

Copy link

commented Jan 13, 2016

I presume you could use anyone of the smtp plugins to get this to work?
E.g. https://wordpress.org/plugins/wp-smtp/

@minostauros

This comment has been minimized.

Copy link

commented Oct 23, 2017

Thanks @abrichr for amazingly simple solution. Didn't catch that /etc/hosts was the villain.

@janpapenbrock

This comment has been minimized.

Copy link

commented Dec 13, 2017

If you'd like to have all the goodness of @abrichr's above post #30 (comment) (thank you!) without messing with several files, here it is all in one single Dockerfile RUN command.

Bonus: Container will stop when hitting Ctrl+C.

FROM wordpress:apache

RUN \
  #
  # Install sendmail
    apt-get update \
 && apt-get install -y --no-install-recommends sendmail \
 && rm -rf /var/lib/apt/lists/* \
  #
  # Configure php to use sendmail
 && echo "sendmail_path=sendmail -t -i" >> /usr/local/etc/php/conf.d/sendmail.ini \
  #
  # Create script to use as new entrypoint, which
  # 1. Creates a localhost entry for container hostname in /etc/hosts
  # 2. Restarts sendmail to discover this entry
  # 3. Calls original docker-entrypoint.sh
 && echo '#!/bin/bash' >> /usr/local/bin/docker-entrypoint-wrapper.sh \
 && echo 'set -euo pipefail' >> /usr/local/bin/docker-entrypoint-wrapper.sh \
 && echo 'echo "127.0.0.1 $(hostname) localhost localhost.localdomain" >> /etc/hosts' >> /usr/local/bin/docker-entrypoint-wrapper.sh \
 && echo 'service sendmail restart' >> /usr/local/bin/docker-entrypoint-wrapper.sh \
 && echo 'exec docker-entrypoint.sh "$@"' >> /usr/local/bin/docker-entrypoint-wrapper.sh \
 && chmod +x /usr/local/bin/docker-entrypoint-wrapper.sh

ENTRYPOINT ["docker-entrypoint-wrapper.sh"]
CMD ["apache2-foreground"]
@Julianoe

This comment has been minimized.

Copy link

commented Dec 16, 2017

Hi @janpapenbrock as i am quite new to Docker, just to be clear: what would be the steps to make this work?
Until now i used a docker-compose.yml. Should i add something like (see inside the code)

version: '3'

services:
   db:
     container_name: ${CONTAINER_DB_NAME}
     image: mysql:5.7
     restart: unless-stopped
     volumes:
        - ${DB_PATH}:/var/lib/mysql
     environment:
       MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
       MYSQL_DATABASE: ${MYSQL_DATABASE}
       MYSQL_USER: ${MYSQL_USER}
       MYSQL_PASSWORD: ${MYSQL_PASSWORD}

   wordpress:
     depends_on:
       - db
     container_name: ${CONTAINER_WP_NAME}
     image: wordpress:${WORDPRESS_IMAGE}
     restart: unless-stopped
     volumes:
       - ${WP_CORE}:/var/www/html
       - ${WP_CONTENT}:/var/www/html/wp-content
     environment:
       WORDPRESS_DB_HOST: ${CONTAINER_DB_NAME}:3306
       WORDPRESS_DB_NAME: ${MYSQL_DATABASE}
       WORDPRESS_DB_USER: ${MYSQL_USER}
       WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD}
       WORDPRESS_TABLE_PREFIX: ${WORDPRESS_TABLE_PREFIX}
       VIRTUAL_HOST: ${DOMAINS}
       LETSENCRYPT_HOST: ${DOMAINS}
       LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL}
     build:
      context: .
      dockerfile: Dockerfile
# I added the Dockerfile you suggested as it is
# and added this build part

networks:
    default:
       external:
         name: ${NETWORK}


I'm confortable with docker-compose and setting up containers but i can't make the mail part working on my wordpress containers :/

@Julianoe

This comment has been minimized.

Copy link

commented Dec 18, 2017

Just to be clear the thing i want the server to be able to is for example send a "forgotten password" email confirmation. No newsletters or anything like that.
@abrichr maybe you can guide me a little here. Should i rebuild an image with the info you provided and mount a container with that said image?

@janpapenbrock

This comment has been minimized.

Copy link

commented Dec 18, 2017

@Julianoe

Yes, it should work. I spotted in your docker-compose.yml you have both image and build defined for wordpress service.

However, I decided to publish this exact image to Docker Hub and I am successfully using it like so:

services:
  wordpress:
    image: hochzehn/wordpress-sendmail:4.9-php7.1-apache

If you have further questions I'm happy to help on Gitter.

@ruucm-working

This comment has been minimized.

Copy link

commented Dec 24, 2017

@janpapenbrock

it works on my new site!

but I think SPF should be added to domain

@drzraf

This comment has been minimized.

Copy link

commented Feb 20, 2018

Any chance to see @pierreozoux plugin been bundled and configurable via environment?
Those who want to do it the docker way can still use an external docker image for the MTA, but the WP plugin/hooks would be needed anyway.

@eduardo-marcolino

This comment has been minimized.

Copy link

commented Mar 23, 2018

@lazyfrosch thank you !

@orlando

This comment has been minimized.

Copy link

commented Apr 18, 2018

This is what I ended up doing to get working SMTP with environment variables, I'm appending this code to wp-config.php

/* SMTP Settings */
add_action( 'phpmailer_init', 'mail_smtp' );
function mail_smtp( $phpmailer ) {
  $phpmailer->isSMTP();
  $phpmailer->Host = getenv('WORDPRESS_SMTP_HOST');
  $phpmailer->SMTPAutoTLS = true;
  $phpmailer->SMTPAuth = true;
  $phpmailer->Port = getenv('WORDPRESS_SMTP_PORT');
  $phpmailer->Username = getenv('WORDPRESS_SMTP_USERNAME');
  $phpmailer->Password = getenv('WORDPRESS_SMTP_PASSWORD');
  
  // Additional settings
  $phpmailer->SMTPSecure = "tls";
  $phpmailer->From = getenv('WORDPRESS_SMTP_FROM');
  $phpmailer->FromName = getenv('WORDPRESS_SMTP_FROM_NAME');
}

You can check how it's integrated in the Dockerfile in this repo (https://github.com/debtcollective/docker-wordpress/)

@controlcde

This comment has been minimized.

Copy link

commented Apr 24, 2018

@orlando: Could you please send a PR to get your code into the project? Sounds like the integration of @lazyfrosch code base.

@orlando

This comment has been minimized.

Copy link

commented Apr 24, 2018

@controlcde not sure if they want to merge something like this. but if they want to, it's easier to modify the Dockerfile and the main script instead

@naum

This comment has been minimized.

Copy link

commented Jun 21, 2018

Attempted the solution that @janpapenbrock graciously provided and sendmail is setup and appears to work from PHP WP functions but mail internally fails with a "SMTP; 550 Host unknown" diagnostic code.

What am I missing?

@benyanke

This comment has been minimized.

Copy link

commented Jul 17, 2018

Can confirm @orlando 's solution works. Any chance this might be committed to the repo? Would the admins be open to a PR?

@pcmanprogrammeur

This comment has been minimized.

Copy link

commented Jul 19, 2018

Here is my solution in the Dockerfile:

RUN apt-get install -y ssmtp
RUN echo "sendmail_path = /usr/sbin/ssmtp -t" >> /usr/local/etc/php/conf.d/sendmail.ini
RUN sed -i -e 's/mailhub=mail/mailhub=[MY-RELAY-IP]/' /etc/ssmtp/ssmtp.conf
RUN sed -i -e 's/#rewriteDomain=/rewriteDomain=[MY-RELAY-IP]/' /etc/ssmtp/ssmtp.conf
RUN sed -i -e 's/#FromLineOverride=/FromLineOverride=/' /etc/ssmtp/ssmtp.conf
RUN sed -i -e '/hostname=/d' /etc/ssmtp/ssmtp.conf

@port22

This comment has been minimized.

Copy link

commented Jul 31, 2018

ssmtp is propably the best solution as it is very small, does not require a service to be running and installs as the sendmail binary. If the official Wordpress image would include this package, then the entrypoint script could populate the ssmtp.conf via ENV variables at container start.

Can't you guys don't just install ssmtp with the official Image? Then we all would be satisfied and wouldn't have to maintain child images. We'd mount our ssmtp.conf in the container and voila.

@controlcde

This comment has been minimized.

Copy link

commented Oct 5, 2018

I try to realize the configuration with WORDPRESS_CONFIG_EXTRA but the $phpmailer variable will be resolved (or not in this case)

WARNING: The phpmailer variable is not set. Defaulting to a blank string.

and the config looks like

// WORDPRESS_CONFIG_EXTRA
/* SMTP Settings */
add_action( 'phpmailer_init', 'mail_smtp' );
function mail_smtp(  ) {
->isSMTP();
->Host = 'mailServer';
->SMTPAutoTLS = true;
->SMTPAuth = true;
->Port = 587;
...

How could I escape the variable $phpmailer?

@yosifkit

This comment has been minimized.

Copy link
Member

commented Oct 5, 2018

@controlcde, Are you setting WORDPRESS_CONFIG_EXTRA via a compose or stack file? If so you would need to put $$phpmailer so that docker-compose / docker stack will put a literal $ rather than trying to replace the variable in the yaml. (https://docs.docker.com/v17.09/compose/compose-file/#variable-substitution)

@controlcde

This comment has been minimized.

Copy link

commented Oct 18, 2018

@yosifkit You're right. With the Double-$ the correct entries will be made in the config file. But it doesn't work - I think the WORDPRESS_CONFIG_EXTRA should be add at the end of wp-config.php to get the email settings working.

@packoman

This comment has been minimized.

Copy link

commented Oct 21, 2018

Hi @pcmanprogrammeur, @timwsuqld, @md5,
(sorry for spamming you guys, but I am bit desperate)
I am trying to follow your suggestions here to setup E-Mail in a Wordpress container using ssmtp. Unfortunately without success thusfar.
Here is what I have:

wordpress docker file content:

FROM wordpress:4.9

RUN apt-get update
RUN apt-get install -y ssmtp

COPY ssmtp.conf /etc/ssmtp/ssmtp.conf

RUN echo "sendmail_path = /usr/sbin/ssmtp -t" >> /usr/local/etc/php/conf.d/sendmail.ini

ssmtp.conf:

root=myuser@gmail.com
mailhub=smtp.gmail.com:587
AuthUser=myuser
AuthPass=mypassword
UseSTARTTLS=Yes
UseTLS=Yes
hostname=localhost

When I test things out by requesting a password recovery E-mail I get the following error message in the browser:

The email could not be sent.
Possible reason: your host may have disabled the mail() function.

with this URL: https://mydomain.com/wp-login.php?action=lostpassword

However I can send mails using ssmtp by logging into the container using

docker exec -it my_wordpress_docker_container /bin/bash

and doing

echo "This message is sent correctly!" | ssmtp -vvv myuser@gmail.com

Can anyone tell me what I am missing? Any help is much appreciated, thanks!

@ClashTheBunny

This comment has been minimized.

Copy link

commented Nov 2, 2018

@packoman I had the same problem when I didn't have the sendmail.ini in place before php start. Also, I've seen many places that they put quotes around the command:
RUN echo "sendmail_path = \"/usr/sbin/ssmtp -t\"" >> /usr/local/etc/php/conf.d/sendmail.ini

@igorivaniuk

This comment has been minimized.

Copy link

commented Nov 17, 2018

@packoman need allow www-data to send mail

FROM wordpress:4.9

RUN apt-get update
RUN apt-get install -y ssmtp

COPY ssmtp.conf /etc/ssmtp/ssmtp.conf
COPY revaliases /etc/ssmtp/revaliases

RUN echo "sendmail_path = /usr/sbin/ssmtp -t" >> /usr/local/etc/php/conf.d/sendmail.ini

revaliases

root:myuser@gmail.com:smtp.gmail.com:465
www-data:myuser@gmail.com:smtp.gmail.com:465

Also for gmail read this:

https://support.google.com/mail/answer/7126229

https://www.google.com/accounts/DisplayUnlockCaptcha

@falconmick

This comment has been minimized.

Copy link

commented Nov 30, 2018

I found the following postfix relay: https://github.com/wader/postfix-relay

I found the maintainer still is working on it and it has support for DKIM which is all i needed. I just added to the functions.php file the following:

add_action( 'phpmailer_init', 'wpse8170_phpmailer_init' );
function wpse8170_phpmailer_init( PHPMailer $phpmailer ) {
    // connect to the SMTP server running in our internal network
    $phpmailer->Host = 'smtp';
    $phpmailer->Port = 25;
    $phpmailer->SMTPAuth = false;
    $phpmailer->SMTPSecure = false;
    $phpmailer->IsSMTP();
}

Where smtp is the name of my postfix relay container (which thus resolves to the correct IP without exposing to the internets)

I then used the following config inside of my docker-compose.yml to get the image up n running

  volumes:
    dkim-data:

  wordpress:
	...
    depends_on:
      ...
      - smtp # added depends_on because wordpress depends on it.. that being said probably not required
    ...

  smtp:
    image: mwader/postfix-relay
    restart: always
    container_name: sova-smtp
    environment:
      - POSTFIX_myhostname=awesomesite.com.au
      - OPENDKIM_DOMAINS=awesomesite.com.au
    volumes:
      - dkim-data:/etc/opendkim/keys
    expose:
      - "25"
@joeldeteves

This comment has been minimized.

Copy link

commented Dec 13, 2018

I would consider msmtp instead. It is probably a little better than ssmtp, because ssmtp afaik is unmaintained.

https://marlam.de/msmtp/
https://wiki.archlinux.org/index.php/msmtp

@Kantankerus

This comment has been minimized.

Copy link

commented Dec 19, 2018

I would consider msmtp instead. It is probably a little better than ssmtp, because ssmtp afaik is unmaintained.

https://marlam.de/msmtp/
https://wiki.archlinux.org/index.php/msmtp

@joeldeteves I researched this separately and have come to the same conclusion. msmtp seems to be the way forward and fills largely the same exact role as ssmtp, only better (fewer bugs, improved system compatability) and more recently maintained. It appears Arch has completely dropped ssmtp from its repositories and I see Cygwin apparently supports msmtp now as well, which was apparently one of the platforms keeping ssmtp alive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.