SMTP-сервер Greenmail не работает должным образом как пользовательский образ докера

Я пытался запустить сервер зеленой почты в приложении с весенней загрузкой и докеризовать его, чтобы я мог использовать его в качестве локального почтового сервера для проверки функциональности почтовой проверки в моем исходном приложении.

Образ докера работает правильно при запуске с помощью команды docker-compose up -d и конечных точек, протестированных с помощью клиента REST.

Проблема возникает, когда я пытаюсь подключить его из исходного приложения для тестирования с помощью образа докера, запущенного в контейнере.

Ниже добавлена ​​трассировка исключения, когда я пытался отправить письмо на mock-сервер.

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 и docker-compose.yml mail-mock-server добавлены ниже.

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

И сервер зеленой почты запускается в основном классе следующим образом.

@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("[email protected]", "test", "test");
    smtpServer.start();
    return smtpServer;
  }
}

После создания образа докера и запуска контейнера докера с помощью команды docker-compose up -d я попробовал следующие конфигурации для bean-компонента JavaMailSender в файле application.yml моего исходного приложения.

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. Но когда я пытаюсь сделать то же самое в докере, он не работает с исключением подключения.

Отсутствует ли какая-либо другая конфигурация в моем исходном приложении или приложении с имитацией сервера?

Любая помощь будет оценена.

С точки зрения вашего приложения, служба SMTP не работает на localhost.

David Maze 04.12.2018 13:39

@DavidMaze: Но когда я проверил с помощью netstat, сервер SMTP прослушивает порт 8585. И конечные точки можно проверить с помощью клиента REST.

Sachin 04.12.2018 13:45

Вам нужно выставить порт, а не 127.0.0.1 в 0.0.0.0, и выставить его. внутри докера он локален для контейнера докеров. поэтому не будет слушать код, запущенный на хост-машине

v_sukt 04.12.2018 13:54
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
3
1 414
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проверяли ли вы после запуска контейнера докеров, есть ли какая-либо служба, прослушивающая указанный вами порт? Для этого [windows / linux] есть команда netstat. Если служба не прослушивает, это даст вам ошибку не может подключиться к серверу.

docker exec -ti <container> bash

может использоваться для Linux как базовые образы. Или попробуйте вести подробные журналы из вашей службы smtp.

CMD будет единственным процессом, работающим в контейнере, если в нем нет диспетчера процессов.

Неясно, «работает ли он при выполнении как java -jar», когда вы пытаетесь выполнить команду CMD или вне докера на локальном компьютере. Не могли бы вы уточнить.

Как обсуждалось в чате -

Сервер находится внутри контейнера, настроенного для прослушивания 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 config 127.0.0.1:8585:8585 можно изменить на 8585: 8585 для прослушивания всех адресов хоста, таких как переадресация портов или ip хоста, кроме ip loopback.

вы можете просто обновить его? будет лучше для всех, кто также пытается вам помочь, вы видите порт 8585 по локальному адресу - попробуйте netstat -tulpen

v_sukt 04.12.2018 13:50

ОК, сервис слушает. Но как ваш код пытается это связать? из того же контейнера или из другого контейнера?

v_sukt 04.12.2018 13:52

Когда этот образ докера запущен, я пытаюсь подключить его из другого приложения, запущенного как приложение весенней загрузки. Он находится вне контейнера.

Sachin 04.12.2018 13:54

правильно. IP 127.0.0.1 является локальным внутри контейнера. так что разоблачение не решит проблему. Он не будет слушать внешнее соединение. Считайте, что это похоже на запуск вашего кода в виртуальной машине, которую вы можете прослушать на 0.0.0.0:8585 и раскрыть его, поделитесь дальнейшей проблемой

v_sukt 04.12.2018 13:55

Итак, что нужно сделать, чтобы решить эту проблему? Было бы лучше, если бы вы могли предложить конфигурацию в моем docker-compose.yml

Sachin 04.12.2018 13:56

Позвольте нам продолжить обсуждение в чате.

v_sukt 04.12.2018 13:56

Другие вопросы по теме