如何使用IntelliJ调试在Docker中运行的应用程序?

35

我有一个在Docker中运行的Jetty应用程序。我想使用本地的IntelliJ来调试此应用程序。我使用版本14.1,在安装了Docker Integration插件后。

在Clouds选项下,我使用单击“+”时显示的默认值。IntelliJ文档表示这应该是可以的。

API URL: http://127.0.0.1:2376
Certificates folder: <empty>

我不确定这些用于什么,因此我不知道这些值是否正确。

在“运行/调试配置”下,我正在使用Docker部署,并使用以下值:

Deployment: Docker Image
Image ID: The docker image ID 
Container name: The name of the container
当我试图运行这个程序时,我遇到了javax.ws.rs.ProcessingException异常: org.apache.http.conn.HttpHostConnectException: 连接到http://127.0.0.1:2376 [/127.0.0.1]失败:连接被拒绝。
显然,我使用的API URL值是不正确的。 有什么建议可以提供吗?
我的调试选项为:
 -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n -Djava.compiler=NONE
5个回答

28

算了吧,我其实不需要 Docker 集成插件。看起来这个插件更适合通过 Intellij 直接部署和管理 Docker 而不是用于调试。

为了调试我在 Docker 容器内运行的 Jetty 应用程序,我只需进行远程调试:

Run | Edit configurations | + | Remote

由于我使用了默认的远程调试选项,命令行参数已经是可以的。我只需要改变“主机”设置。在这里,我使用了我在 Docker 容器内设置的主机名。


1
非常感谢您的帮助。通过 Docker 集成使用调试并没有起作用。现在我只需运行我的 Docker 集成配置来启动服务器,然后运行远程调试器进行调试。效果很好。 - Ezekiel Victor
1
@JoppeGeluykens 当然可以。你基本上只需要像连接到任何远程服务器一样连接到代码即可。恰好这个远程服务器位于一个 Docker 容器内部。 - Somaiah Kumbera
@SomaiahKumbera 当我配置远程调试器时,似乎无法设置断点。有什么想法或需要额外的配置吗? - Joppe Geluykens
@JoppeGeluykens 这很奇怪。如果您从IDE收到消息,可以连接到远程服务器,则应该能够设置断点。如果您无法设置断点,则我怀疑您在Docker镜像中运行的代码与IDE中的代码不同。尝试在几个地方单击以进行断点设置。如果您得到不匹配的断点,则说明您的代码不同。 - Somaiah Kumbera
当我点击 + 时,我没有看到“远程”选项。有什么解决办法吗? - ZottoSL
显示剩余5条评论

11

请按照以下方式运行docker镜像:

docker run -d -p 8080:8080  -p 5005:5005 \
    -e JAVA_TOOL_OPTIONS="-agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=n" \
    imagename:tagname

对于Java 11及以上版本,请将JAVA_TOOL_OPTIONS替换为“-agentlib:jdwp = transport = dt_socket,address = *:5005,server = y,suspend = n”。

Intellij配置步骤:

  1. 从菜单栏中点击运行编辑配置 → 在左侧面板中点击远程 → 点击+符号添加调试配置

  2. 添加新配置后,以调试模式=连接到远程JVM。 填写主机和端口号

  3. 选择要调试的模块类路径,然后应用设置

  4. 要连接,请从运行菜单中运行上述远程配置。

example config


你忘记在 agentlib:jdwp=... 前面加上 - 了 ;) - ᴠɪɴᴄᴇɴᴛ

7
在Java 8中,JDK支持JAVA_TOOL_OPTIONS环境变量,因此要为任何Java应用程序启用调试器,您可以将以下参数添加到您的docker run命令中:
-p 8000:8000 -e "JAVA_TOOL_OPTIONS=\"-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n\""

然后启动一个远程调试会话,连接到localhost:8000。


1
这对于使用docker-compose配置为环境变量非常方便:D - snap
3
外部双引号不是必需的:JAVA_TOOL_OPTIONS="-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n" - ᴠɪɴᴄᴇɴᴛ

2
如果您正在使用Docker Compose,请将以下更改应用于Dockerfile和docker-compose.yml
Dockerfile
FROM openjdk:11-jdk-slim
ARG JAR_FILE=report-manager/target/*.jar
ENV JAVA_TOOL_OPTIONS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

添加ENV JAVA_TOOL_OPTIONS部分

docker-compose.yml

services:
  report-manager:
    build:
      context: .
      dockerfile: report-manager/Dockerfile/
    image: report-manager
    ports:
      - "5032:5032"
      - "5005:5005"

打开5005端口

然后创建IntelliJ Idea常规的远程调试配置,并在部署Docker容器后运行它。


1
如果您无法访问Dockerfile,则也可以在Docker Compose中添加环境变量。 - Adheli Tavares
对于我的Java容器,我需要将0.0.0.0:5005放在*:5005的位置,否则我会收到“ERROR: transport error 202: gethostbyname: unknown host”错误提示。 - Christopher Thomas

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接