如何在Docker镜像中锁定eclipse-temurin与Maven版本?
锁定Docker中Eclipse Temurin(Java)和Maven的版本
问题背景
我运行着一个简单的Java应用,代码如下:
package com.lbg.test_artifact; import java.io.IOException; public class App { public static void main( String[] args ) throws IOException { int i; do { System.out.write(i = System.in.read()); } while (i != -1); } }
当前的Dockerfile如下:
FROM eclipse-temurin WORKDIR /usr/src/app COPY . . RUN apt-get update && apt-get install -y --no-install-recommends maven RUN mvn clean package CMD ["java", "-jar", "./target/test-artifact-0.0.1-SNAPSHOT.jar"]
希望锁定Java(eclipse-temurin)和Maven的版本,但尝试用apt-get install maven=<版本号>时总是提示“包未找到”。
解决方案
1. 锁定Eclipse Temurin(Java)版本
Eclipse Temurin镜像通过标签指定具体版本,格式为eclipse-temurin:<Java版本>-<jdk/jre>-<操作系统>,例如:
eclipse-temurin:17-jdk-jammy(Java 17 JDK,基于Ubuntu Jammy)eclipse-temurin:11-jre-focal(Java 11 JRE,基于Ubuntu Focal)eclipse-temurin:8-jdk-bullseye(Java 8 JDK,基于Debian Bullseye)
修改Dockerfile的基础镜像行即可锁定Java版本:
FROM eclipse-temurin:17-jdk-jammy
2. 锁定Maven版本
针对apt-get安装Maven找不到指定版本的问题,有三种可靠解决方式:
方式一:匹配仓库版本号用apt-get安装
Debian/Ubuntu仓库中的Maven包版本号并非单纯的3.8.6这类格式,而是带有后缀(比如3.8.6-1),需先确认当前基础镜像仓库中可用的Maven版本:
# 在容器内执行以下命令查看可用版本 apt-cache madison maven
找到对应版本后,修改安装命令:
RUN apt-get update && apt-get install -y --no-install-recommends maven=3.8.6-1
方式二:手动下载指定版本Maven(不受仓库限制)
直接获取指定版本的Maven二进制包,避免依赖系统仓库:
FROM eclipse-temurin:17-jdk-jammy WORKDIR /usr/src/app # 安装依赖工具 RUN apt-get update && apt-get install -y --no-install-recommends wget tar # 下载并解压指定版本的Maven(这里以3.9.6为例) RUN wget https://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz \ && tar -xzf apache-maven-3.9.6-bin.tar.gz -C /opt \ && rm apache-maven-3.9.6-bin.tar.gz # 配置Maven环境变量 ENV PATH="/opt/apache-maven-3.9.6/bin:${PATH}" COPY . . RUN mvn clean package CMD ["java", "-jar", "./target/test-artifact-0.0.1-SNAPSHOT.jar"]
方式三:多阶段构建(推荐,镜像更精简)
先用指定版本的Maven镜像构建项目,再将生成的jar包复制到Java镜像中,避免在运行镜像中安装构建工具:
# 构建阶段:使用指定版本的Maven镜像 FROM maven:3.9.6-eclipse-temurin-17 AS build WORKDIR /usr/src/app COPY pom.xml . COPY src ./src RUN mvn clean package # 运行阶段:使用指定版本的Java镜像 FROM eclipse-temurin:17-jre-jammy WORKDIR /usr/src/app COPY --from=build /usr/src/app/target/test-artifact-0.0.1-SNAPSHOT.jar . CMD ["java", "-jar", "./test-artifact-0.0.1-SNAPSHOT.jar"]
这种方式既锁定了Maven和Java的版本,又能大幅减小最终镜像体积,运行镜像中仅包含Java运行环境。
内容的提问来源于stack exchange,提问作者user1775718




