You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

停止Docker容器后容器内.jar应用仍持续运行的解决方法

问题场景
  • 开发栈:Eclipse环境下使用Maven、MicroProfile框架开发OpenLiberty服务,打包为.jar格式Java应用,本地可通过java -jar name.jar命令直接运行
  • 初始镜像配置:基于OpenJDK官方镜像制作容器镜像,初始Dockerfile内容如下:
FROM openjdk:12-oracle
COPY projectname.jar /projectname.jar
CMD ["java", "-jar", "projectname.jar"]
  • 操作流程:执行docker build -t takemealong .构建镜像,再执行docker run -p 8080:8080 --name TakeMeAlong_Container takemealong创建并启动容器
  • 异常现象:容器启动后运行正常,可正常访问服务index.html页面;但执行停止容器操作、甚至完全退出Docker后,Web服务仍在后台持续运行:任务管理器中可见名为Vmmem的相关进程,index.html页面依然可以正常访问。
问题根因
  • Vmmem是Windows系统下WSL2子系统的运行进程,Docker Desktop默认基于WSL2后端运行,默认配置下退出Docker Desktop不会主动关闭WSL2实例,未终止的进程、端口映射规则会残留在WSL2运行态中
  • 当前Dockerfile直接将Java进程作为容器内PID 1进程运行,OpenJDK12版本在PID 1场景下默认不会响应Docker发出的SIGTERM终止信号,执行docker stop时JVM收不到退出指令,不会主动终止
  • 普通docker stop操作默认等待10秒超时,超时后如果进程仍未退出,不会强制清理残留,进程会被WSL2实例持有,持续占用端口运行
解决方案

按以下步骤配置调整,即可实现停止容器时同步终止内部jar应用进程:

  1. 修改Dockerfile,引入tini轻量init进程负责转发系统信号,解决PID 1进程不响应SIGTERM的问题,修改后内容如下:
FROM openjdk:12-oracle
RUN microdnf install -y tini
COPY projectname.jar /projectname.jar
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["java", "-jar", "/projectname.jar"]

修改完成后重新执行docker build -t takemealong .构建新镜像即可。
2. 停止容器时直接使用强制删除命令,替代普通的stop操作,命令执行后会直接终止容器内所有进程并清理容器实例:

docker rm -f TakeMeAlong_Container
  1. 后续启动容器时追加--rm参数,容器停止时会自动清理自身,避免进程残留:
docker run -d --rm -p 8080:8080 --name TakeMeAlong_Container takemealong
  1. 如果退出Docker Desktop后仍存在Vmmem进程占用、服务可访问的情况,直接在Windows命令行执行以下命令关闭所有WSL2实例,即可彻底清理所有残留进程:
wsl --shutdown

验证标准:完成上述操作后,刷新服务对应页面确认无法访问,任务管理器中Vmmem进程的CPU、内存占用归零,即代表进程已完全终止。

内容的提问来源于stack exchange,提问作者Eve__BC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 15:18:13