Отладка Tomcat в контейнере Docker

У меня CoreOS работает в Vagrant. IP-адрес бродячей частной сети 192.168.111.1. Внутри CoreOS находится док-контейнер с Tomcat 8.0.32. Практически все работает нормально (развертывание приложений и т. Д.), Только отладка - нет. Tomcat сопоставлен с портом 8080, а порт JPDA должен быть 8000.

Факты

Tomcat JPDA настроен на:

JDPA_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000

Он начинается с команды catalina.sh jpda start. Вывод в консоли при запуске с docker-compose:

tomcat | Listening for transport dt_socket at address: 8000

Из информации о контейнере я предполагаю, что порты отображаются так, как должны:

CONTAINER ID        IMAGE       COMMAND      CREATED             STATUS              PORTS                                            NAMES
dcae1e0148f8        tomcat      "/run.sh"    8 minutes ago       Up 8 minutes        0.0.0.0:8000->8000/tcp, 0.0.0.0:8080->8080/tcp   tomcat

Мой образ докера основан на этом Dockerfile.

Проблема

При попытке запустить конфигурацию удаленной отладки (снимок экрана ниже) я получаю сообщение об ошибке Error running Debug: Unable to open debugger port (192.168.111.1:8000): java.net.ConnectException "Connection refused". Я пробовал все, от изменения различной конфигурации, но не повезло. Я что-то упускаю?

введите описание изображения здесь


person CAPS LOCK    schedule 23.02.2016    source источник


Ответы (8)


Я использую для этого следующую команду:

docker run -it --rm \
  -e JPDA_ADDRESS=8000 \
  -e JPDA_TRANSPORT=dt_socket \
  -p 8888:8080 \
  -p 9000:8000 \
  -v D:/tc/conf/tomcat-users.xml:/usr/local/tomcat/conf/tomcat-users.xml \
  tomcat:8.0 \
  /usr/local/tomcat/bin/catalina.sh jpda run

Объяснение

  • -e JPDA_ADDRESS = 8000
    порт отладки в контейнере, переданный как переменная среды
  • -e JPDA_TRANSPORT = dt_socket
    тип транспорта для отладки как сокет, переданный как переменная среды
  • -p 8888: 8080
    выставить порт 8080 tomcat на хосте как порт 8888
  • -p 9000: 8000
    выставить порт отладки Java 8000 на хосте как порт 9000
  • -v {host-file}: {container-file}
    перезаписать tomcat-user.xml моим локальным включением, так как мне нужен доступ к диспетчеру api.
    опустите эту строку, если это не обязательно для вашего варианта использования
  • tomcat: 8.0
    см. https://hub.docker.com/_/tomcat/
  • /usr/local/tomcat/bin/catalina.sh jpda run
    команда для запуска в контейнере
person Peter    schedule 20.11.2016
comment
Установка JPDA_ADDRESS имеет решающее значение для работы в докере. Tomcat по умолчанию использует привязку к localhost вместо 0.0.0.0, поэтому порт отладки не может быть открыт. - person tstevens; 22.02.2018
comment
@tstevens, да, да, да. Очень полезно. Чтобы быть более конкретным: -e JPDA_ADDRESS = 0.0.0.0: 8000 - person Software Prophets; 19.02.2020
comment
Для JDK 9+ см. Ответ ниже: stackoverflow.com/a/55745249/840714. Вам нужен JPDA_ADDRESS=*:<PORT>. - person Druckles; 20.08.2020

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

JPDA_ADDRESS=*:8100
person Sebastian Heikamp    schedule 18.04.2019
comment
Спасибо, поймал эту ошибку с помощью: openjdk: 8u131-jre-alpine - person Dmitry Surin; 26.12.2019

Вы всегда можете обновить Dockerfile на что-то вроде следующего: -

FROM tomcat:8-jre8
MAINTAINER me

ADD target/app.war /usr/local/tomcat/webapps/app.war

ENV JPDA_ADDRESS="8000"
ENV JPDA_TRANSPORT="dt_socket"

EXPOSE 8080 8000
ENTRYPOINT ["catalina.sh", "jpda", "run"]

Однако это означает, что в вашем файле докеров по умолчанию включена отладка, что, вероятно, не подходит для производственной среды.

person bobmarksie    schedule 25.11.2016

Попробуйте добавить в свой Dockerfile

ENV JPDA_ADDRESS=8000
ENV JPDA_TRANSPORT=dt_socket

Меня устраивает

person Bukharov Sergey    schedule 11.07.2016

Я решил аналогичную, если не ту же проблему, при использовании docker-compose.

Это связано с неправильной передачей переменных среды из файла docker-compose.yml.

См. мой проблема переполнения стека:

person Olmstov    schedule 29.07.2017

Для меня это чище:

docker run -e JAVA_TOOL_OPTIONS="-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n" -p 8000:8000 tomcat:8.5-jdk8

Таким образом, вам не нужно изменять Dockerfile вашего контейнера.

Объяснение: все версии java проверяют переменную среды JAVA_TOOL_OPTIONS: https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/envvars002.html

person Joan    schedule 24.06.2019

Вам необходимо убедиться, что порт 8080 открыт для подключения к IntelliJ. То есть при запуске докера вам потребуется что-то вроде docker run -p 8080:8080

Например, я могу выполнить подобное требование, выполнив указанные ниже шаги / проверки.

Вот как выглядит моя команда запуска докера:

sudo docker run --privileged=true -d -p 63375:63375 -p 63372:8080 -v /tmp/:/usr/local/tomcat/webapps/config <container name>:<tag>

ПРИМЕЧАНИЕ. Я выставляю дополнительный порт 63375 как на контейнере, так и на моем хосте. Тот же порт, который я использую в CATALINA_OPTS ниже.

Вот как выглядит моя точка входа (для изображения, которое я создаю). ПРИМЕЧАНИЕ. Я использую CATALINA_OPTS. Кроме того, я использую maven для создания изображения, поэтому ниже извлекается из pom.xml.

<entryPoint>
    <shell>cd /usr/local/tomcat/bin; CATALINA_OPTS="-agentlib:jdwp=transport=dt_socket,address=63375,server=y,suspend=n" catalina.sh run</shell>
</entryPoint>
person Tyagi Akhilesh    schedule 03.03.2016
comment
В разделе «Факты» находится информация о контейнере, которая указывает, что порты tomcat отображаются правильно. С помощью команды lsof я проверил, что порт 8000 свободен. Я считаю, что JPDA_OPTS также настроены правильно, как предполагает журнал. В любом случае спасибо за попытку. - person CAPS LOCK; 03.03.2016
comment
Какую команду docker вы использовали для запуска контейнера? Здесь это важно. Я не уверен, когда вы говорите, что порт был свободен, вы имеете в виду, что он был открыт и слушал? Кроме того, где он был свободен / открыт - внутри контейнера ИЛИ на хосте (где вы, вероятно, запускаете intellij), на котором запущен контейнер? - person Tyagi Akhilesh; 03.03.2016
comment
Свободный / открытый порт на хосте: чтобы убедиться, что никакое другое приложение его не использует. Контейнер Tomcat работает с docker-compose (вместе с другими контейнерами). Порты представлены в файле docker-compose. Команда запуска - по умолчанию (из образа catalina.sh jpda run). - person CAPS LOCK; 03.03.2016
comment
Я имел в виду команду запуска докера специально -p <hostPort>:<containerPort> part. - person Tyagi Akhilesh; 03.03.2016
comment
Я использую docker-compose, поэтому в моем случае нет команды docker run. Однако docker-compose port и docker run -p - это одно и то же (8000: 8000 и 8080: 8080). - person CAPS LOCK; 03.03.2016
comment
Аааа .. Понятно. Я ничего не знаю о сочинении. Но исключение, которое сообщает intellij, - это только индикатор сопоставления портов. - person Tyagi Akhilesh; 03.03.2016
comment
Должно быть что-то еще. В противном случае я бы не смог развернуть приложение на сервере через порт 8080. - person CAPS LOCK; 03.03.2016
comment
межсетевой экран iptables ?? просто догадываюсь - person Tyagi Akhilesh; 03.03.2016

У меня аналогичная установка в моей локальной среде. Я включил JPDA_ADDRESS в качестве переменной среды в Dockerfile и воссоздал контейнеры.

ENV JPDA_ADDRESS 8000

#Expose port 8080, JMX port 13333 & Debug port 8000
EXPOSE 8080 13333 8000

CMD ["tail", "-f", "/dev/null"]  
person raghu    schedule 03.05.2017