本地mvn package运行正常,Docker构建时该命令返回exit code 1如何解决
首先需要明确:你遇到的exit code: 1不是编译类错误,是Maven命令执行失败的通用返回码,结合你排查到的SSL握手失败、报文提前结束的日志,本质是Docker构建阶段Maven依赖拉取失败导致的。
本地与Docker构建的核心差异
之所以本地执行mvn package正常,Docker内执行失败,核心差异有三点:
- 本地Maven有已缓存的依赖包,不需要全量从远程仓库拉取,而Docker构建的builder阶段是全新的空环境,所有依赖都需要重新下载
- 本地Maven通常有自定义的镜像源、代理等配置,官方
maven:3.6-jdk-11镜像默认使用Maven中央仓库,无任何自定义配置 - Docker容器的虚拟网卡和宿主机物理网卡的网络配置不同,常见MTU不匹配、运营商对Docker流量的限制、容器内CA证书缺失等问题,都会导致远程仓库访问异常
排查与解决方案
1. 给容器内Maven配置镜像源
在项目根目录新建settings.xml配置稳定的Maven镜像源,示例如下:
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <mirrors> <!-- 可根据所在区域选择速度最快的镜像源,比如阿里云、欧洲区域镜像等 --> <mirror> <id>aliyunmaven</id> <mirrorOf>central</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url> </mirror> </mirrors> </settings>
修改Dockerfile,将配置文件复制到容器内Maven的配置目录:
# 在COPY pom.xml前添加如下行 COPY settings.xml /usr/share/maven/conf/settings.xml
2. 挂载本地Maven缓存跳过依赖拉取
构建时直接挂载宿主机的Maven缓存目录,复用本地已经下载好的依赖,完全避开容器内下载依赖的环节:
docker build -t my-rest-api-1.0 . -v ~/.m2:/root/.m2
3. 修复Docker网络异常
- 先验证容器访问Maven中央仓库的连通性:执行
docker run --rm maven:3.6-jdk-11 curl -v https://repo1.maven.org/maven2/,确认是否存在SSL报错、连接超时问题 - 如果是报文提前结束,大概率是MTU不匹配导致,修改Docker daemon配置,将容器网络MTU调整为和宿主机网卡一致的数值(通常设为1400即可解决大部分场景问题)
- 如果是SSL握手失败,临时测试可在Maven命令添加参数跳过SSL校验:
RUN mvn package -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true
4. 优化构建流程规避容器内打包
如果网络问题始终无法解决,可以直接在本地完成打包后,将jar包复制到运行镜像中,彻底去掉builder阶段的Maven构建环节,修改后的Dockerfile如下:
FROM adoptopenjdk/openjdk11:alpine-slim COPY target/my-rest-api-*.jar /my-rest-api.jar ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -jar /my-rest-api.jar
这种方式构建速度更快,也完全规避了容器内的网络依赖问题。
内容的提问来源于stack exchange,提问作者The Coder
相关产品推荐
相关产品推荐

