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

Sendmail configuration doesn't work inside docker image #3960

Closed
Ainillia opened this issue Jan 10, 2023 · 3 comments
Closed

Sendmail configuration doesn't work inside docker image #3960

Ainillia opened this issue Jan 10, 2023 · 3 comments
Labels

Comments

@Ainillia
Copy link

Ainillia commented Jan 10, 2023

Describe the Bug

Hello,

I am having an issue about sending mail through bookstack installed in docker container. I'm using sendmail configuration.
Sendmail is working on the host and sends back 220. -bs option works also on host. But not inside docker / busybox.

Thank you for your help.

=== Details ===

.env config file :

MAIL_DRIVER=sendmail
MAIL_FROM_NAME="BookStack"
MAIL_FROM=bookstack@edited.be
MAIL_HOST=localhost
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

Test from host (working, sends back 220) :

[root@labbck0003 bookstack_containers]# /usr/sbin/sendmail -bs
220 [labbck0003.nrb.be](http://labbck0003.nrb.be/) ESMTP Postfix

Test from docker (doc says to use /usr/sbin/sendmail -bs => https://www.bookstackapp.com/docs/admin/email-webhooks/ )

[root@labbck0003 bookstack_containers]# docker exec -it bookstack bash

root@0d1a19ce0480:/# /usr/sbin/sendmail -bs
/usr/sbin/sendmail: unrecognized option: b
BusyBox v1.34.1 (2022-07-19 20:11:24 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](http://smtp.gmail.com:25/)
                openssl s_client -quiet -tls1 -connect [smtp.gmail.com:465](http://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
        -amPLAIN        or AUTH PLAIN
                        (-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.

Laravel log upon creating an user with sending mail or clicking the test send mail :
#Laravel Log

[2023-01-10 22:51:19] production.ERROR: Failed to save user avatar image

[2023-01-10 22:51:19] production.ERROR: Expected response code 220 but got an empty response {"userId":1,"exception":"[object] (Swift_TransportException(code: 0): Expected response code 220 but got an empty response at /app/www/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php:447)

[stacktrace]

#0 /app/www/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php(360): Swift_Transport_AbstractSmtpTransport->assertResponseCode()

#1 /app/www/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php(147): Swift_Transport_AbstractSmtpTransport->readGreeting()

#2 /app/www/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SendmailTransport.php(50): Swift_Transport_AbstractSmtpTransport->start()

#3 /app/www/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer.php(65): Swift_Transport_SendmailTransport->start()

#4 /app/www/vendor/laravel/framework/src/Illuminate/Mail/Mailer.php(521): Swift_Mailer->send()

#5 /app/www/vendor/laravel/framework/src/Illuminate/Mail/Mailer.php(288): Illuminate\\Mail\\Mailer->sendSwiftMessage()

#6 /app/www/vendor/laravel/framework/src/Illuminate/Notifications/Channels/MailChannel.php(65): Illuminate\\Mail\\Mailer->send()

#7 /app/www/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(148): Illuminate\\Notifications\\Channels\\MailChannel->send()

#8 /app/www/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(106): Illuminate\\Notifications\\NotificationSender->sendToNotifiable()

#9 /app/www/vendor/laravel/framework/src/Illuminate/Support/Traits/Localizable.php(19): Illuminate\\Notifications\\NotificationSender->Illuminate\\Notifications\\{closure}()

#10 /app/www/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(109): Illuminate\\Notifications\\NotificationSender->withLocale()

#11 /app/www/vendor/laravel/framework/src/Illuminate/Notifications/ChannelManager.php(54): Illuminate\\Notifications\\NotificationSender->sendNow()

#12 /app/www/vendor/laravel/framework/src/Illuminate/Notifications/SendQueuedNotifications.php(104): Illuminate\\Notifications\\ChannelManager->sendNow()

#13 /app/www/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\\Notifications\\SendQueuedNotifications->handle()

#14 /app/www/vendor/laravel/framework/src/Illuminate/Container/Util.php(40): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()

#15 /app/www/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(93): Illuminate\\Container\\Util::unwrapIfClosure()

#16 /app/www/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(37): Illuminate\\Container\\BoundMethod::callBoundMethod()

#17 /app/www/vendor/laravel/framework/src/Illuminate/Container/Container.php(653): Illuminate\\Container\\BoundMethod::call()

#18 /app/www/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(128): Illuminate\\Container\\Container->call()

#19 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Bus\\Dispatcher->Illuminate\\Bus\\{closure}()

#20 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#21 /app/www/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(132): Illuminate\\Pipeline\\Pipeline->then()

#22 /app/www/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(120): Illuminate\\Bus\\Dispatcher->dispatchNow()

#23 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Queue\\CallQueuedHandler->Illuminate\\Queue\\{closure}()

#24 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#25 /app/www/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(122): Illuminate\\Pipeline\\Pipeline->then()

#26 /app/www/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(70): Illuminate\\Queue\\CallQueuedHandler->dispatchThroughMiddleware()

#27 /app/www/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(98): Illuminate\\Queue\\CallQueuedHandler->call()

#28 /app/www/vendor/laravel/framework/src/Illuminate/Queue/SyncQueue.php(43): Illuminate\\Queue\\Jobs\\Job->fire()

#29 /app/www/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(253): Illuminate\\Queue\\SyncQueue->push()

#30 /app/www/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(229): Illuminate\\Bus\\Dispatcher->pushCommandToQueue()

#31 /app/www/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(77): Illuminate\\Bus\\Dispatcher->dispatchToQueue()

#32 /app/www/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(217): Illuminate\\Bus\\Dispatcher->dispatch()

#33 /app/www/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(76): Illuminate\\Notifications\\NotificationSender->queueNotification()

#34 /app/www/vendor/laravel/framework/src/Illuminate/Notifications/ChannelManager.php(39): Illuminate\\Notifications\\NotificationSender->send()

#35 /app/www/vendor/laravel/framework/src/Illuminate/Notifications/RoutesNotifications.php(18): Illuminate\\Notifications\\ChannelManager->send()

#36 /app/www/app/Auth/Access/UserInviteService.php(23): BookStack\\Auth\\User->notify()

#37 /app/www/app/Auth/UserRepo.php(95): BookStack\\Auth\\Access\\UserInviteService->sendInvitation()

#38 /app/www/app/Http/Controllers/UserController.php(97): BookStack\\Auth\\UserRepo->create()

#39 /app/www/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php(29): BookStack\\Http\\Controllers\\UserController->BookStack\\Http\\Controllers\\{closure}()

#40 /app/www/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php(442): Illuminate\\Database\\Connection->transaction()

#41 /app/www/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(261): Illuminate\\Database\\DatabaseManager->__call()

#42 /app/www/app/Http/Controllers/UserController.php(98): Illuminate\\Support\\Facades\\Facade::__callStatic()

#43 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): BookStack\\Http\\Controllers\\UserController->store()

#44 /app/www/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\\Routing\\Controller->callAction()

#45 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(262): Illuminate\\Routing\\ControllerDispatcher->dispatch()

#46 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Route.php(205): Illuminate\\Routing\\Route->runController()

#47 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(721): Illuminate\\Routing\\Route->run()

#48 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}()

#49 /app/www/app/Http/Middleware/Authenticate.php(23): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#50 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): BookStack\\Http\\Middleware\\Authenticate->handle()

#51 /app/www/app/Http/Middleware/Localization.php(45): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#52 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): BookStack\\Http\\Middleware\\Localization->handle()

#53 /app/www/app/Http/Middleware/RunThemeActions.php(26): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#54 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): BookStack\\Http\\Middleware\\RunThemeActions->handle()

#55 /app/www/app/Http/Middleware/CheckEmailConfirmed.php(47): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#56 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): BookStack\\Http\\Middleware\\CheckEmailConfirmed->handle()

#57 /app/www/app/Http/Middleware/PreventAuthenticatedResponseCaching.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#58 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): BookStack\\Http\\Middleware\\PreventAuthenticatedResponseCaching->handle()

#59 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#60 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle()

#61 /app/www/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#62 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle()

#63 /app/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#64 /app/www/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest()

#65 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Session\\Middleware\\StartSession->handle()

#66 /app/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#67 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle()

#68 /app/www/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#69 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle()

#70 /app/www/app/Http/Middleware/ApplyCspRules.php(33): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#71 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): BookStack\\Http\\Middleware\\ApplyCspRules->handle()

#72 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#73 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(723): Illuminate\\Pipeline\\Pipeline->then()

#74 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(698): Illuminate\\Routing\\Router->runRouteWithinStack()

#75 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(662): Illuminate\\Routing\\Router->runRoute()

#76 /app/www/vendor/laravel/framework/src/Illuminate/Routing/Router.php(651): Illuminate\\Routing\\Router->dispatchToRoute()

#77 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(167): Illuminate\\Routing\\Router->dispatch()

#78 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}()

#79 /app/www/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#80 /app/www/app/Http/Middleware/TrustProxies.php(41): Illuminate\\Http\\Middleware\\TrustProxies->handle()

#81 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): BookStack\\Http\\Middleware\\TrustProxies->handle()

#82 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#83 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()

#84 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle()

#85 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#86 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle()

#87 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#88 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle()

#89 /app/www/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()

#90 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(142): Illuminate\\Pipeline\\Pipeline->then()

#91 /app/www/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(111): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()

#92 /app/www/public/index.php(53): Illuminate\\Foundation\\Http\\Kernel->handle()

#93 {main}

"}

Steps to Reproduce

  1. Edit sendmail config
  2. Restart docker containers
  3. Check env file is correct
  4. Check host sendmail is correct
  5. Push on button to test email (or create an user with send mail request)

Expected Behaviour

Mail goes through, test succeeds and users can be created via email request.

Screenshots or Additional Context

No response

Browser Details

Vivaldi 5.6 (also tested chrome/firefox)

Exact BookStack Version

22.11.1

PHP Version

Docker managed (latest)

Hosting Environment

RHEL8.5
Docker version latest
Docker Images latest (Bookstack too)

CONTAINER ID   IMAGE                             COMMAND   CREATED          STATUS          PORTS                                                                                  NAMES
0d1a19ce0480   [lscr.io/linuxserver/bookstack](http://lscr.io/linuxserver/bookstack)     "/init"   21 minutes ago   Up 21 minutes   80/tcp, 443/tcp                                                                        bookstack
d36ad4aa80e5   jc21/nginx-proxy-manager:latest   "/init"   21 minutes ago   Up 21 minutes   0.0.0.0:80-81->80-81/tcp, :::80-81->80-81/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp   bookstack_proxy
0542e91bec3d   [lscr.io/linuxserver/mariadb](http://lscr.io/linuxserver/mariadb)       "/init"   21 minutes ago   Up 21 minutes   3306/tcp                                                                               bookstack_db
@ssddanbrown
Copy link
Member

Hi @Ainillia,
The sendmail option expects one of the more modern sendmail implementations that supports the -bs flag, which is common on modern operating systems (Postfix for example). Looks like this isn't supported by the busybox implementation that's used in the container you are using. Makes sense that's what's available by default in that container image since containers often target minimal surface area but you so end up with differences compared to non-container/minimal environments.

A different sendmail implementation could be installed and used but I'm not sure on the complexities involved in getting a working sendmail system going from a minimal (alpine based in this case) container environment.
I'd advise going the SMTP route to be honest.

@Ainillia
Copy link
Author

Hello,

Thank you for your answer.

I have tried the SMTP configuration in the meantime, and it works from the container. Emails are going through. Many thanks !

To avoid issues like this one in the future, and for all the (future) users, maybe you should either (or both ?) :

  • Update the documentation to mention using sendmail within the lscr contrainer does not work and we should use SMTP instead.
  • Add a failsafe to detect that sendmail isn't working properly (switches/parameters are not supported). And display a string to the user that it isn't supported and they should configure the SMTP method instead.

That may be easy to switch configuration but in a large enterprise it can take a while (firewall openings, login requests, configurations, authorizations,..).

You can close the issue whenever you want.

@ssddanbrown
Copy link
Member

Thanks for the response. Sure, we could look at extra steps if this becomes a bigger problem (Although we don't have ownership or provide specific documentation for external projects like the LSIO container), but this is a rare issue so not sure it's worthwhile dedicating efforts/resources at this time.

Will therefore close this off.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants