[GH-ISSUE #153] Sending emails from PHP container to Mailpit running in another container does nothing #103

Closed
opened 2026-03-15 12:34:09 +03:00 by kerem · 11 comments
Owner

Originally created by @back-2-95 on GitHub (Aug 14, 2023).
Original GitHub issue: https://github.com/axllent/mailpit/issues/153

We are replacing MailHog with Mailpit in our tool Stohenge: https://github.com/druidfi/stonehenge/pull/76

We have a problem getting email sent from PHP containers to host's port 1025. Noteworthy is that sending emails with curl from those same containers work just fine which I guess at least verifies that Mailpit is running just fine. When sending email through PHP (sendmail), we get no errors to logs or on terminal.

This is current setup & situation from the PR above ^^:

Mailpit is attached to localhost:1025 from a Docker container and is running with following flags:

mailpit --verbose --smtp=0.0.0.0:1025 --smtp-auth-accept-any --smtp-auth-allow-insecure

Contents of email.txt:

From: sender@example.com
To: recipient@example.com
Subject: Email Subject

This is the body of the email.
It can contain multiple lines of text.

Works

Sending email from host (macOS) with Curl:

curl smtp://localhost:1025 --mail-from sender@example.com --mail-rcpt recipient@example.com --upload-file email.txt

Sending email from another container with Curl:

curl smtp://host.docker.internal:1025 --mail-from sender@example.com --mail-rcpt recipient@example.com --upload-file email.txt

Not working:

Sendmail configured for PHP as inside another container:

sendmail_path => /usr/sbin/sendmail -S host.docker.internal:1025 => /usr/sbin/sendmail -S host.docker.internal:1025

Sending email from another container with PHP mail() function:

php -r 'mail("recipient@example.com", "Test subject", "This is our test message", "From: sender@example.com");'
Originally created by @back-2-95 on GitHub (Aug 14, 2023). Original GitHub issue: https://github.com/axllent/mailpit/issues/153 We are replacing MailHog with Mailpit in our tool Stohenge: https://github.com/druidfi/stonehenge/pull/76 We have a problem getting email sent from PHP containers to host's port 1025. Noteworthy is that sending emails with curl from those same containers work just fine which I guess at least verifies that Mailpit is running just fine. When sending email through PHP (sendmail), we get no errors to logs or on terminal. This is current setup & situation from the PR above ^^: Mailpit is attached to `localhost:1025` from a Docker container and is running with following flags: ```shell mailpit --verbose --smtp=0.0.0.0:1025 --smtp-auth-accept-any --smtp-auth-allow-insecure ``` Contents of `email.txt`: ``` From: sender@example.com To: recipient@example.com Subject: Email Subject This is the body of the email. It can contain multiple lines of text. ``` ## Works Sending email from host (macOS) with Curl: ```shell curl smtp://localhost:1025 --mail-from sender@example.com --mail-rcpt recipient@example.com --upload-file email.txt ``` Sending email from another container with Curl: ```shell curl smtp://host.docker.internal:1025 --mail-from sender@example.com --mail-rcpt recipient@example.com --upload-file email.txt ``` ## Not working: Sendmail configured for PHP as inside another container: ```ini sendmail_path => /usr/sbin/sendmail -S host.docker.internal:1025 => /usr/sbin/sendmail -S host.docker.internal:1025 ``` Sending email from another container with PHP `mail()` function: ```shell php -r 'mail("recipient@example.com", "Test subject", "This is our test message", "From: sender@example.com");' ```
kerem closed this issue 2026-03-15 12:34:14 +03:00
Author
Owner

@axllent commented on GitHub (Aug 14, 2023):

Considering you're running Mailpit in verbose mode, what output are you getting from the Mailpit container when you try connect/send from the PHP container?

I think it's one of a few things:

Firstly, is there are particular reason you're including --smtp-auth-accept-any or even --smtp-auth-allow-insecure? Please try with just mailpit --verbose --smtp=0.0.0.0:1025 as I'm pretty sure you're not proving any login details from sendmail, so adding --smtp-auth-accept-any means Mailpit tells the SMTP client it requires authentication ~ even if it accepts anything (curl just ignores this).

Secondly, what sendmail is your PHP container using? If it's the busybox implementation including in Alpine Linux, please note that it is extremely buggy, especially with PHP >=8. Based on #87 it turned out that this busybox's sendmail replaces all \n with \r\n - except that as from PHP8, all line breaks are already \r\n, so busybox's sendmail makes this \r\r\n. I'm no a C programmer, so my understanding may be off, but it definitely looked like the cause of the original issue to me.

You should be able to test PHP's mail() in verbose mode like this:

php -d "sendmail_path=/usr/sbin/sendmail -v -S host.docker.internal:1025 -t" -r 'mail("recipient@example.com", "Test subject", "This is our test message", "From: sender@example.com");'

If you're getting errors similar to that bug report I linked to, then you will probably need to replace sendmail with a compliant sendmail version.

Lastly, I assume

sendmail_path => /usr/sbin/sendmail -S host.docker.internal:1025 => /usr/sbin/sendmail -S host.docker.internal:1025

is a typo? It should be just sendmail_path=/usr/sbin/sendmail -S host.docker.internal:1025

I hope this helps and that you're able to debug your issue.

<!-- gh-comment-id:1677021453 --> @axllent commented on GitHub (Aug 14, 2023): Considering you're running Mailpit in verbose mode, what output are you getting from the Mailpit container when you try connect/send from the PHP container? I think it's one of a few things: Firstly, is there are particular reason you're including `--smtp-auth-accept-any` or even `--smtp-auth-allow-insecure`? Please try with just `mailpit --verbose --smtp=0.0.0.0:1025` as I'm pretty sure you're not proving any login details from sendmail, so adding `--smtp-auth-accept-any` means Mailpit tells the SMTP client it requires authentication ~ even if it accepts anything (curl just ignores this). Secondly, what `sendmail` is your PHP container using? If it's the busybox implementation including in Alpine Linux, please note that it is extremely buggy, especially with PHP >=8. Based on #87 it turned out that this busybox's sendmail replaces all `\n` with `\r\n` - except that as from PHP8, all line breaks are already `\r\n`, so busybox's sendmail makes this `\r\r\n`. I'm no a C programmer, so my understanding may be off, but it definitely looked like the cause of the original issue to me. You should be able to test PHP's mail() in verbose mode like this: ``` php -d "sendmail_path=/usr/sbin/sendmail -v -S host.docker.internal:1025 -t" -r 'mail("recipient@example.com", "Test subject", "This is our test message", "From: sender@example.com");' ``` If you're getting errors similar to that bug report I linked to, then you will probably need to replace sendmail with a compliant sendmail version. Lastly, I assume ``` sendmail_path => /usr/sbin/sendmail -S host.docker.internal:1025 => /usr/sbin/sendmail -S host.docker.internal:1025 ``` is a typo? It should be just `sendmail_path=/usr/sbin/sendmail -S host.docker.internal:1025` I hope this helps and that you're able to debug your issue.
Author
Owner

@back-2-95 commented on GitHub (Aug 14, 2023):

Sendmail is at least this container Alpine's BusyBox v1.36.1

php -d "sendmail_path=/usr/sbin/sendmail -v -S host.docker.internal:1025 -t" -r 'mail("recipient@example.com", "Test subject", "This is our test message", "From: sender@example.com");'

gives failed at the end:

sendmail: recv:'220 497699dce1d7 Mailpit ESMTP Service ready'
sendmail: send:'EHLO druidfi.docker.so'
sendmail: recv:'250-497699dce1d7 greets druidfi.docker.so'
sendmail: recv:'250-SIZE 0'
sendmail: recv:'250-AUTH LOGIN PLAIN'
sendmail: recv:'250 ENHANCEDSTATUSCODES'
sendmail: send:'MAIL FROM:<druid@druidfi.docker.so>'
sendmail: recv:'250 2.1.0 Ok'
sendmail: send:'RCPT TO:<recipient@example.com>'
sendmail: recv:'250 2.1.5 Ok'
sendmail: send:'DATA'
sendmail: recv:'354 Start mail input; end with <CR><LF>.<CR><LF>'
'endmail: send:'To: recipient@example.com
'endmail: send:'Subject: Test subject
'endmail: send:'From: sender@example.com
'endmail: send:'
'endmail: send:'This is our test message
sendmail: send:'.'
sendmail: recv:'451 4.3.5 Unable to process mail'
sendmail: . failed
<!-- gh-comment-id:1677038419 --> @back-2-95 commented on GitHub (Aug 14, 2023): Sendmail is at least this container Alpine's BusyBox v1.36.1 ```shell php -d "sendmail_path=/usr/sbin/sendmail -v -S host.docker.internal:1025 -t" -r 'mail("recipient@example.com", "Test subject", "This is our test message", "From: sender@example.com");' ``` gives failed at the end: ``` sendmail: recv:'220 497699dce1d7 Mailpit ESMTP Service ready' sendmail: send:'EHLO druidfi.docker.so' sendmail: recv:'250-497699dce1d7 greets druidfi.docker.so' sendmail: recv:'250-SIZE 0' sendmail: recv:'250-AUTH LOGIN PLAIN' sendmail: recv:'250 ENHANCEDSTATUSCODES' sendmail: send:'MAIL FROM:<druid@druidfi.docker.so>' sendmail: recv:'250 2.1.0 Ok' sendmail: send:'RCPT TO:<recipient@example.com>' sendmail: recv:'250 2.1.5 Ok' sendmail: send:'DATA' sendmail: recv:'354 Start mail input; end with <CR><LF>.<CR><LF>' 'endmail: send:'To: recipient@example.com 'endmail: send:'Subject: Test subject 'endmail: send:'From: sender@example.com 'endmail: send:' 'endmail: send:'This is our test message sendmail: send:'.' sendmail: recv:'451 4.3.5 Unable to process mail' sendmail: . failed ```
Author
Owner

@axllent commented on GitHub (Aug 14, 2023):

Your output looks identical to #87 - this is not a Mailpit bug, it looks like the same busybox sendmail bug likely caused by \r\r\n (which is not valid/compliant).

As a work-around for the buggy sendmail, you could set your existing sendmail as such:

sendmail_path=sh -c 'dos2unix | /usr/sbin/sendmail -S host.docker.internal:1025 -t'

The dos2unix command replaces all \r\n with just \n, which busybox's sendmail then turns back into \r\n - and everything is compliant again.

You can test this with:

php -d "sendmail_path=sh -c 'dos2unix | /usr/sbin/sendmail -S host.docker.internal:1025 -t'" -r 'mail("recipient@example.com", "Test subject", "This is our test message", "From: sender@example.com");'
<!-- gh-comment-id:1677055302 --> @axllent commented on GitHub (Aug 14, 2023): Your output looks identical to #87 - this is not a Mailpit bug, it looks like the same busybox sendmail bug likely caused by `\r\r\n` (which is not valid/compliant). As a work-around for the buggy sendmail, you could set your existing sendmail as such: ``` sendmail_path=sh -c 'dos2unix | /usr/sbin/sendmail -S host.docker.internal:1025 -t' ``` The `dos2unix` command replaces all `\r\n` with just `\n`, which busybox's sendmail then turns back into `\r\n` - and everything is compliant again. You can test this with: ``` php -d "sendmail_path=sh -c 'dos2unix | /usr/sbin/sendmail -S host.docker.internal:1025 -t'" -r 'mail("recipient@example.com", "Test subject", "This is our test message", "From: sender@example.com");' ```
Author
Owner

@back-2-95 commented on GitHub (Aug 14, 2023):

Workaround seems to work, I tested it on a few projects. Problem still persists on projects where we are not the authors of the PHP Docker images used and if they don't support changing sendmail configuration with PHP_SENDMAIL_PATH env variable.

<!-- gh-comment-id:1677134058 --> @back-2-95 commented on GitHub (Aug 14, 2023): Workaround seems to work, I tested it on a few projects. Problem still persists on projects where we are not the authors of the PHP Docker images used and if they don't support changing sendmail configuration with `PHP_SENDMAIL_PATH` env variable.
Author
Owner

@axllent commented on GitHub (Aug 15, 2023):

Whilst I understand your issue (not always having control over the docker images used), this is appears to still be an issue with this sendmail implementation, which is sending non-RFC-compliant headers to Mailpit (or any SMTP server for that matter). In my view, Mailpit is doing exactly what is was mean to - it is (among other things) an SMTP testing tool too, and so it isn't accepting a non-compliant SMTP connection.

The problem should be fixed upstream, ie: in busybox's sendmail, which would then resolve the issue everywhere once fixed and rolled out. I have just reported the issue in their bug tracker, so we'll see what happens there and what their response is.

I will still look in the meantime whether there is a work-around for Mailpit (to accept the non-compliant headers), however last time I looked it didn't seem possible, and as I just said, it defeats the point of testing SMTP if it allows non-compliant headers.

<!-- gh-comment-id:1678403261 --> @axllent commented on GitHub (Aug 15, 2023): Whilst I understand your issue (not always having control over the docker images used), this is appears to still be an issue with this sendmail implementation, which is sending non-RFC-compliant headers to Mailpit (or any SMTP server for that matter). In my view, Mailpit is doing exactly what is was mean to - it is (among other things) an SMTP testing tool too, and so it isn't accepting a non-compliant SMTP connection. The problem should be fixed upstream, ie: in busybox's sendmail, which would then resolve the issue everywhere once fixed and rolled out. I have just [reported the issue](https://bugs.busybox.net/show_bug.cgi?id=15724) in their bug tracker, so we'll see what happens there and what their response is. I will still look in the meantime whether there is a work-around for Mailpit (to accept the non-compliant headers), however last time I looked it didn't seem possible, and as I just said, it defeats the point of testing SMTP if it allows non-compliant headers.
Author
Owner

@back-2-95 commented on GitHub (Aug 15, 2023):

You mention in #87 alternative sendmail available for Alpine being msmtp? Is it somewhat drop-in replacement? If so, I could use that in out internal images.

<!-- gh-comment-id:1678410018 --> @back-2-95 commented on GitHub (Aug 15, 2023): You mention in #87 alternative sendmail available for Alpine being `msmtp`? Is it somewhat drop-in replacement? If so, I could use that in out internal images.
Author
Owner

@axllent commented on GitHub (Aug 15, 2023):

That was (from memory) a replacement, but not sure about it being "drop-in". But ... before you continue - I have been looking into a working solution. The workaround (I haven't released this yet) will resolve the issue for you, with an option to turn it off. I'm not 100% happy about "fixing" messages by default, but with careful consideration I think that this is the better approach as it's clear that this is a blocker for many developers who use busybox's sendmail implementation in testing.

Most users, like yourself, will just get an error and not understand what the actual problem is, and some major mailservers like postfix already auto-correct this anyway. I expect to have this "feature" released in the next couple of days.

<!-- gh-comment-id:1678436082 --> @axllent commented on GitHub (Aug 15, 2023): That was (from memory) a replacement, but not sure about it being "drop-in". But ... before you continue - I have been looking into a working solution. The workaround (I haven't released this yet) will resolve the issue for you, with an option to turn it off. I'm not 100% happy about "fixing" messages by default, but with careful consideration I think that this is the better approach as it's clear that this is a blocker for many developers who use busybox's sendmail implementation in testing. Most users, like yourself, will just get an error and not understand what the actual problem is, and some major mailservers like postfix already auto-correct this anyway. I expect to have this "feature" released in the next couple of days.
Author
Owner

@axllent commented on GitHub (Aug 16, 2023):

I have just released this "fix" in v1.8.2. Please let me know if it resolves your sending error?

<!-- gh-comment-id:1679993767 --> @axllent commented on GitHub (Aug 16, 2023): I have just released this "fix" in v1.8.2. Please let me know if it resolves your sending error?
Author
Owner

@back-2-95 commented on GitHub (Aug 16, 2023):

Just tried it:

It works IF I change the php.ini sendmail setting from PHP_SENDMAIL_PATH=/usr/sbin/sendmail -S host.docker.internal:1025 to PHP_SENDMAIL_PATH=/usr/sbin/sendmail -S host.docker.internal:1025 -t

<!-- gh-comment-id:1680013896 --> @back-2-95 commented on GitHub (Aug 16, 2023): Just tried it: It works IF I change the php.ini sendmail setting from `PHP_SENDMAIL_PATH=/usr/sbin/sendmail -S host.docker.internal:1025` to `PHP_SENDMAIL_PATH=/usr/sbin/sendmail -S host.docker.internal:1025 -t`
Author
Owner

@axllent commented on GitHub (Aug 16, 2023):

Ahh yes, the -t is required IF your mailer (PHP) doesn't provide the recipients on the commandline when using that sendmail. This is expected behaviour and the default in the php.ini.

Glad it's working!

<!-- gh-comment-id:1680037217 --> @axllent commented on GitHub (Aug 16, 2023): Ahh yes, the `-t` is required *IF* your mailer (PHP) doesn't provide the recipients on the commandline when using that sendmail. This is expected behaviour and the [default](https://github.com/php/php-src/blob/master/php.ini-production#L1103) in the `php.ini`. Glad it's working!
Author
Owner

@back-2-95 commented on GitHub (Aug 16, 2023):

Yes! Thank you for the support, I can now add Mailpit as Mailhog replacement in our tooling and projects just need to add that -t flag to PHP_SENDMAIL_PATH.

<!-- gh-comment-id:1680038841 --> @back-2-95 commented on GitHub (Aug 16, 2023): Yes! Thank you for the support, I can now add Mailpit as Mailhog replacement in our tooling and projects just need to add that `-t` flag to `PHP_SENDMAIL_PATH`.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/mailpit#103
No description provided.