Docker Compose部署Spring Boot应用报错:无法访问jar文件
这个问题的核心原因很明确:你在Docker Compose的core服务中挂载了主机的./core目录到容器的/usr/src/core,这直接覆盖了容器镜像中原本通过Dockerfile复制进去的myjar.jar文件所在的目录。
为什么单独运行镜像没问题?
当你直接用docker run启动core_image时,没有挂载本地目录,容器内的/usr/src/core目录是镜像构建时的状态——里面包含了Dockerfile中ADD ./myproject/target/myjar.jar /usr/src/core复制进去的jar文件,所以Java能正常找到它。
为什么Docker Compose运行就报错?
而通过docker-compose up运行时,- './core:/usr/src/core'这个挂载操作会把容器内的/usr/src/core目录完全替换成你主机上的./core目录。如果你的主机./core目录里没有myjar.jar(毕竟这个jar是你构建镜像时从myproject/target复制进去的,主机目录里可能只有源码,没有编译后的jar),自然会出现unable to access jarfile myjar.jar的错误。
解决方案
根据你的需求,有两种常见的处理方式:
1. 移除覆盖jar目录的挂载(最简单直接)
如果不需要把主机的./core目录挂载到容器里,直接删除core服务volumes中的- './core:/usr/src/core'这一行即可:
core: image: core_image container_name: core-container build: context: ./core dockerfile: Dockerfile volumes: # 移除这行,避免覆盖容器内的jar文件 # - './core:/usr/src/core' - './algorithms:/usr/src/algorithms' ports: - 8080:8080 environment: - JARFILE=myjar.jar - JAVA_OPTIONS=-Djava.security.egd=file:/dev/./urandom
2. 按需挂载,避免覆盖jar所在目录
如果你确实需要挂载主机的部分文件/目录到容器(比如开发时热更新配置或源码),不要挂载整个/usr/src/core,而是挂载具体的子目录或文件。例如:
core: # ...其他配置不变 volumes: # 只挂载需要的子目录,比如配置文件目录 - './core/src/main/resources:/usr/src/core/src/main/resources' - './algorithms:/usr/src/algorithms'
这样既满足了挂载需求,又不会覆盖包含jar文件的容器目录。
另外,你也可以检查下主机的./core目录中是否存在myjar.jar——如果不存在,那挂载后容器里自然找不到这个文件,这也验证了我们的分析。
内容的提问来源于stack exchange,提问作者diekunstderfuge

