Greenmail SMTP服务器无法作为自定义docker映像正常运行

时间:2018-12-04 12:27:21

标签: java spring docker docker-compose javamail

我试图在春季启动应用程序中启动greenmail服务器并对其进行docker化,以便可以将其用作本地邮件模拟服务器来对原始应用程序中的邮件功能进行行为测试。

使用docker-compose up -d命令启动docker镜像并通过REST客户端测试了端点后,docker镜像可以正常工作。

当我尝试从原始应用程序将其连接以进行测试,并在容器中运行的docker映像时发生问题。

以下是我尝试向模拟服务器发送邮件时的异常跟踪。

  

org.springframework.mail.MailSendException:邮件服务器连接   失败嵌套的异常是javax.mail.MessagingException:无法   连接到SMTP主机:127.0.0.1,端口:8585,响应:-1。失败的   消息:javax.mail.MessagingException:无法连接到SMTP   主机:127.0.0.1,端口:8585,响应:-1         在org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:446)   〜[spring-context-support-5.1.2.RELEASE.jar:5.1.2.RELEASE]         在org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:359)   〜[spring-context-support-5.1.2.RELEASE.jar:5.1.2.RELEASE]         在org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:354)   〜[spring-context-support-5.1.2.RELEASE.jar:5.1.2.RELEASE]         在com.test.controller.MailTestController.sendMail(MailTestController.java:80)   〜[main /:na]         在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)〜[na:1.8.0_171]         在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)   〜[na:1.8.0_171]         在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)   〜[na:1.8.0_171]         在java.lang.reflect.Method.invoke(Method.java:498)〜[na:1.8.0_171]         ................................................... ................................................... ...         ................................................... ................................................... ...

     

由于:javax.mail.MessagingException:无法连接到SMTP主机:127.0.0.1,端口:8585,响应:-1         在com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2197)   〜[javax.mail-1.6.2.jar:1.6.2]         在com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:740)   〜[javax.mail-1.6.2.jar:1.6.2]         在javax.mail.Service.connect(Service.java:366)〜[javax.mail-1.6.2.jar:1.6.2]         在org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:515)   〜[spring-context-support-5.1.2.RELEASE.jar:5.1.2.RELEASE]         在org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:435)   〜[spring-context-support-5.1.2.RELEASE.jar:5.1.2.RELEASE]         ...省略了100个普通框架

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

DockerFile :-

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服务器。

@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中尝试相同操作时,它会失败并出现连接异常。

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

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

您在运行docker容器后是否检查了指定端口上是否监听任何服务?有用于此[windows / linux]的netstat命令。如果没有服务在监听,则会提示您无法连接服务器。

docker exec -ti <container> bash

可以用于linux之类的基础映像。或者尝试从您的smtp服务中获取一些详细的日志。

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

当您尝试在本地计算机上尝试命令CMD或外部docker时,尚不清楚“它作为java -jar执行时是否有效”。你能澄清一下吗?

如聊天中所讨论-

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

您需要将smtp服务器配置为侦听0.0.0.0,因为使用127.0.0.1使其侦听来自容器内部的连接,因为127.0.0.1的容器和127.0.0.1 fo容器与主机的本地主机不同客户端尝试连接的计算机。 因此,进行以下更改即可-

 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)。