如何确保Gradle构建的Java代码在Docker容器中更新生效?
问题背景
我在Docker容器中运行基于Java Spring API的Angular应用,本地修改代码后执行以下流程:
- 前端修改时,执行
ng build构建Angular应用 - 将
/dist目录内容复制到Spring代码库的src/main/resources/static目录(仅前端修改时执行) - 执行
./gradlew build构建Spring应用,且已确认./build/libs/<app-name>-0.0.1-SNAPSHOT.jar文件已更新 - 执行
docker build --no-cache -t <user>:<app-name>构建本地镜像 - 执行
docker run <user>:<app-name>运行容器
但发现容器内的/app/<app-name>.jar并非最新版本,仍然是上次推送的旧代码。我的Dockerfile内容如下:
FROM adoptopenjdk/openjdk11 COPY ./build/libs/<app-name>-0.0.1-SNAPSHOT.jar /app/<app-name>.jar EXPOSE 8080 WORKDIR /app ENTRYPOINT ["java", "-jar", "/app/<app-name>.jar"]
更新说明:计划后续接入CI/CD,但当前需先确保手动流程正常
排查与解决步骤
确认Docker构建上下文路径
执行docker build时,必须保证当前工作目录是Spring项目的根目录(即build/libs所在的父目录)。如果在其他目录执行构建,COPY命令会找不到正确的jar文件,即便加了--no-cache也可能复用旧缓存文件。验证COPY路径的准确性
检查jar包的文件名是否和Dockerfile中的<app-name>-0.0.1-SNAPSHOT.jar完全匹配,比如是否存在版本号变更、拼写错误。可以执行ls -l build/libs/确认文件名,确保和Dockerfile中的一致。强制清理Docker缓存
除了--no-cache参数,还可以手动清理本地无用的镜像和缓存,彻底消除缓存干扰:docker system prune -af构建时指定完整上下文路径
可以在docker build命令中通过绝对路径指定Spring项目根目录,避免上下文路径错误:docker build --no-cache -t <user>:<app-name> -f ./Dockerfile /path/to/spring-project-root/把
/path/to/spring-project-root/替换为你的Spring项目实际根目录路径。提前验证镜像内容
构建完成后先不运行容器,直接验证镜像内的jar包是否为最新版本:# 查看jar包版本信息 docker run --rm <user>:<app-name> java -jar /app/<app-name>.jar --version # 查看jar包修改时间 docker run -it --rm <user>:<app-name> ls -l /app/<app-name>.jar确认本地镜像为最新构建版本
执行docker images查看镜像列表,检查目标镜像的创建时间,确保运行的是刚构建的最新镜像,而非从远程仓库拉取的旧镜像。
内容的提问来源于stack exchange,提问作者Vihung

