Greenmail SMTP 服务器无法作为自定义 docker 图片正常工作

Greenmail SMTP server is not working properly as custom docker image

我试图在 spring 引导应用程序中启动一个绿色邮件服务器并 docker 对其进行调整,以便我可以将其用作本地邮件模拟服务器以在我的原始应用程序。

当使用 docker-compose up -d 命令和从 REST 客户端测试的端点启动时,docker 图像工作正常。

当我出于测试目的尝试将它从我的原始应用程序连接到容器中的 docker 图像 运行 时,就会出现此问题。

下面添加了我尝试向模拟服务器发送邮件时的异常跟踪。

org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Could not connect to SMTP host: 127.0.0.1, port: 8585, response: -1. Failed messages: javax.mail.MessagingException: Could not connect to SMTP host: 127.0.0.1, port: 8585, response: -1 at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:446) ~[spring-context-support-5.1.2.RELEASE.jar:5.1.2.RELEASE] at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:359) ~[spring-context-support-5.1.2.RELEASE.jar:5.1.2.RELEASE] at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:354) ~[spring-context-support-5.1.2.RELEASE.jar:5.1.2.RELEASE] at com.test.controller.MailTestController.sendMail(MailTestController.java:80) ~[main/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_171] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_171] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_171] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_171] ....................................................................................................... .......................................................................................................

Caused by: javax.mail.MessagingException: Could not connect to SMTP host: 127.0.0.1, port: 8585, response: -1 at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2197) ~[javax.mail-1.6.2.jar:1.6.2] at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:740) ~[javax.mail-1.6.2.jar:1.6.2] at javax.mail.Service.connect(Service.java:366) ~[javax.mail-1.6.2.jar:1.6.2] at org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:515) ~[spring-context-support-5.1.2.RELEASE.jar:5.1.2.RELEASE] at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:435) ~[spring-context-support-5.1.2.RELEASE.jar:5.1.2.RELEASE] ... 100 common frames omitted

DockerFile配置和mail-mock-server的docker-compose.yml添加如下

Docker文件:-

FROM gcr.io/distroless/java:latest

VOLUME /opt/test/

ARG JAR_FILE
COPY libs/mock-mail-server-*.jar /opt/test/mock-mail-server-app.jar
WORKDIR /opt/test/
CMD ["mock-mail-server-app.jar"]

docker-compose.yml:-

version: '3'
services:
  app:
    image: test/mock-mail-server:0.0.1-SNAPSHOT
    container_name: mock-mail-server-app
    ports: 
      - 0.0.0.0:8484:8484
      - 127.0.0.1:8585:8585

greenmail 服务器在主 class 中启动如下。

@SpringBootApplication
public class MailMockServerApplication {

  public static void main(String[] args) {
    SpringApplication.run(MailMockServerApplication.class, args);
  }

  @Bean
  public GreenMail greenMail() {
    GreenMail smtpServer = new GreenMail(new ServerSetup(8585, "127.0.0.1", "smtp"));
    smtpServer.setUser("test.mailer@test.com", "test", "test");
    smtpServer.start();
    return smtpServer;
  }
}

构建 docker 图像并使用命令 docker-compose up -d 启动 docker 容器后,我在原始应用程序的 application.yml 中尝试了 JavaMailSender bean 的以下配置] 文件。

mail:
    default-encoding: UTF-8
    host: ${MAIL_SERVER_HOST:127.0.0.1}
    username: ${MAIL_SERVER_USER_NAME:test}
    password: ${MAIL_SERVER_PASSWORD:test}
    port: ${MAIL_SERVER_PORT:8585}
    properties:
      mail:
        debug: true
        smtp:
          debug: false
          auth: true
          starttls: true
    protocol: smtp
    test-connection: false

同时,当我的模拟邮件服务器应用程序从命令行使用 java -jar 命令时,这工作正常。但是当我在 docker 中尝试相同时,它因连接异常而失败。

我的原始应用程序或模拟服务器应用程序中是否缺少任何其他配置?

如有任何帮助,我们将不胜感激。

您是否在 运行 之后检查 docker 容器是否有任何服务在您指定的端口上侦听?此 [windows/linux] 有 netstat 命令。如果没有服务侦听它会给你无法连接到服务器错误。

docker exec -ti <container> bash

可用于 linux 等基本图像。或者尝试从您的 smtp 服务中获取一些详细的日志。

CMD 将是容器中唯一的进程 运行,除非它有进程管理器。

不清楚 "it works when executed as java -jar" 是在您尝试命令 CMD 时还是在本地计算机上 docker 之外。你能解释一下吗?

正如在聊天中讨论的那样 -

服务器位于配置为侦听 127.0.0.1:8585 的容器内,并且您在主机上公开了相同的端口。
所以要解决这个问题

您需要将您的 smtp 服务器配置为侦听 0.0.0.0,因为使用 127.0.0.1 使其侦听来自容器内部的连接,因为容器的 127.0.0.1 和容器的 127.0.0.1 与主机的本地主机不同客户端尝试连接的机器。 所以下面的变化会做 -

 GreenMail smtpServer = new GreenMail(new ServerSetup(8585, "0.0.0.0", "smtp"));

和应用程序的配置 yaml 文件

 host: ${MAIL_SERVER_HOST:0.0.0.0}

虽然 docker-compose 文件配置 127.0.0.1:8585:8585 可以更改为 8585:8585 以侦听所有主机地址,如端口转发或除环回 ip 以外的主机 ip .