IDEA调试Java+Docker+Tomcat+Spring程序

其实如果广告是Java程序,或者是Spring boot,用IDEA调试都是很简单的事情。

不过最近在维护一个老项目,用的是tomcat8+Java1.7版本,所以本地的开发环境也需要一致。

就用docker搭了一个docker + tomcat环境。

开发之前的第一步,自然是整好调试环境,以便在出错时对程序运行状态和变量有清晰的了解。

以下便是我具体的docker环境。

1 目录结构

.
├── docker-compose.yml          容器启动配置文件
├── conf                        配置目录
│   └── server.xml              Tomcat站点配置文件
└── www                         站点根目录
    ├── awaimai                 站点1根目录
    │   ├── src                 站点1 Java源码
    │   └── target              站点1 编译目录
    └── localhost               站点2根目录

这样的结构可以一个命令:

$ docker-compose up

就能启动服务,并且在所有操作系统上都保持一直。

(这里省略nginx、mysql、redis、activemq等服务目录)

2 docker-compose.yml文件

这是docker搭建环境的一键配置文件,具体内容如下(省略MySQL服务):

version: "3"
services:
  tomcat:
    image: tomcat:8.5.27
    ports:
      - "8080:8080"
      - "5005:5005"
    volumes:
      - ./www:/www:rw
      - ./conf/server.xml:/usr/local/tomcat/conf/server.xml:ro
    environment:
      TZ: Asia/Shanghai
      JPDA_ADDRESS: 5005
      JPDA_TRANSPORT: dt_socket
    command: ["catalina.sh", "jpda", "run"]
    networks:
      - default

  # 需要nginx、mysql、redis、activemq配置都可以在这里加上

networks:
  default:

其中,

8080端口是供浏览器访问的端口,我们暴露到主机,这样就能在主机中访问容器的服务。

5005端口是JPDA使用的调试端口,因为我们的IDEA IDE是在主机,所以也需要暴露这个端口到主机。

接着我们还需要在容器中指定两个环境变量,JPDA_ADDRESS: 5005和JPDA_TRANSPORT: dt_socket,

5005是JPDA使用的端口,我们已经暴露给主机了,所以主机调试用的就是这个端口,socket是JPDA的连接方式。

最后,我们用command: ["catalina.sh", "jpda", "run"],以JPDA方式启动 Tomcat

这样容器就配置成可调试的了。

3 server.xml文件(可选)

顺便再贴上我 server.xml 配置的配置,

<Host name="www.awaimai.com"  appBase="/www/awaimai/target"
      unpackWARs="true" autoDeploy="true" reloadable="true">
</Host>

我的Java代码是在本地的 ./www/awaimai/src/main 目录下,映射到容器的/www/awaimai/src/main目录下。

因为 tomcat 只是运行编译之后的代码,所以源码映射还是不映射到容器都无所谓,

因为我这里直接把 ./www 目录挂过去了,所以目录是对应的。

编译后的的代码在本地 ./www/awaimai/target 目录,映射到容器的 /www/awaimai/target 目录下。

一般来说,target 目录下会有 .war 文件,tomcat 会自动解压为一个目录。

4 IDEA配置

IDEA菜单:Run -> Edit Configurations...

点击左上角的+号,选择Remote

然后填上Host和port,这里的Host是 server.xml 中指定的Host,Port是jpda的端口。

因为我们用的是域名,所以还需要在主机的 /etc/hosts 文件中加上这样一行:

127.0.0.1 www.awaimai.com

这样我们在浏览器中访问:www.awaimai.com:8080,就能访问容器中tomcat服务了。

我的配置如下图:

其实就是改了Host和Port。

然后在IDEA中选择菜单:Run -> Debug myDebug,Debugger的variables窗口显示:

Connected to the target VM, address: 'www.awaimai.com:5050', transport: 'socket'

说明IDEA已经连上docker容器的jpda了。

5 调试

在代码的控制器中打一个断点。

@RequestMapping(value = "/login.do", method = RequestMethod.GET)
public ModelAndView login(HttpServletRequest request) {
   ModelAndView mav = new ModelAndView("login");
   return mav;
}

比如我在第3行打了一个断点,然后在浏览器中访问:

www.awaimai.com:8080/login.do

在IDEA中程序就会停止在断点处,接下来就随便操作了。

 

参考资料:

  1. How to Remotely Debug Application Running on Tomcat From Within Intellij IDEA
  2. Debugging Tomcat in Docker container
  3. How to debug app on tomcat running inside the container