Docker 多阶段构建管理多版本 JDK 和 Maven

目录

一、Docker 构建 JDK 和 Maven 的三种方式

1. 一起构建(统一镜像)

2. 分开构建(独立镜像)​

3. 混合策略(推荐)​

4. 总结

二、Docker 混合策略构建 JDK 和 Maven

1. 检查 Docker 环境和用户权限

2. 创建工作目录结构

3. 创建 Dockerfile 并构建镜像

3.1. 创建基础 Dockerfile (非最终构建产物)

3.2. 创建多阶段构建 Dockerfile (最终构建产物)并构建镜像

4. 创建和使用不同版本的脚本

4.1. 创建JDK切换信息显示脚本 docker-use-jdk(可选)

4.2. 创建Maven切换信息显示脚本 docker-use-maven(可选)

4.3. 创建一个综合开发环境脚本 dev-env


一、Docker 构建 JDK 和 Maven 的三种方式

1. 一起构建(统一镜像)

        将所有 JDK 和 Maven 版本打包到 ​同一个镜像 中,通过环境变量或脚本动态切换版本。Dockerfile 例如:

# 基础层(所有版本共享)
FROM debian:11 AS base
RUN apt-get update && apt-get install -y curl

# 多版本安装层
FROM base AS jdk-maven
ARG JDK_VERSION=11
ARG MAVEN_VERSION=3.8.6
RUN curl -sL "https://jdk.example.com/jdk${JDK_VERSION}.tar.gz" | tar -xz
RUN curl -sL "https://maven.example.com/maven-${MAVEN_VERSION}.tar.gz" | tar -xz
ENV PATH="/jdk${JDK_VERSION}/bin:/maven-${MAVEN_VERSION}/bin:${PATH}"

​        优点

                减少重复层:共享基础层(如操作系统、公共依赖),减少镜像总体积。

                单镜像多用途:通过 docker run --env JDK_VERSION=17 动态指定版本,适合需要频繁切换版本的环境(如 CI/CD)。

                简化标签管理:使用统一镜像标签(如 myimage:latest),通过参数化配置版本。

​        缺点

                镜像臃肿:包含多个 JDK/Maven 版本会增加镜像体积(例如同时安装 JDK8/11/17)。

                潜在冲突:不同版本的环境变量或路径可能冲突(需严格隔离路径)。

                更新复杂:更新某个版本需重建整个镜像。

​                适用场景:需要快速切换版本的本地开发环境;资源有限且镜像存储成本敏感的场景。

2. 分开构建(独立镜像)​

        为每个 JDK 和 Maven 版本组合构建 ​独立镜像,例如:myimage:jdk8-maven3.8.6;myimage:jdk11-maven3.8.6;myimage:jdk17-maven3.9.6

​        优点

                镜像轻量化:每个镜像仅包含必要版本,体积更小。

                隔离性更好:版本之间无路径或依赖冲突。

                更新灵活:更新单个版本只需重建对应镜像。

        ​缺点

                ​存储冗余:不同镜像无法共享基础层(如操作系统层重复占用空间)。

                管理成本高:需维护多个 Dockerfile 或矩阵构建逻辑。

                标签爆炸:版本组合较多时,标签管理复杂(如 jdkX-mavenY)。

        ​适用场景:生产环境需要严格版本隔离;需要精准控制镜像内容的场景(如安全合规)。

3. 混合策略(推荐)​

        结合两者的优点,使用 ​多阶段构建 和 ​镜像分层优化

​        步骤

                基础镜像:构建共享的操作系统层和工具层。Dockerfile 如下:

                ​版本镜像:为每个 JDK 和 Maven 版本构建独立子镜像。Dockerfile 如下:

        ​        按需组合:通过 CI/CD 工具(如 GitHub Actions)生成版本矩阵,yaml如下:

jobs:
  build:
    strategy:
      matrix:
        jdk: [8, 11, 17]
        maven: [3.8.6, 3.9.6]
    steps:
      - name: Build image
        run: |
          docker build --build-arg JDK=${{ matrix.jdk }} --build-arg MAVEN=${{ matrix.maven }} -t myimage:jdk${{ matrix.jdk }}-maven${{ matrix.maven }} .

​        优势

                存储优化:共享基础层,减少冗余。

                ​灵活更新:独立重建特定版本。

                ​生产友好:精准控制镜像内容。

4. 总结

        选择策略时,优先考虑 ​生产需求 和 ​资源限制。大多数团队推荐 ​混合策略 以平衡效率和维护成本。

策略存储效率构建速度维护成本适用场景
一起构建本地开发、快速测试
分开构建生产环境、严格隔离
混合策略平衡存储与灵活性

二、Docker 混合策略构建 JDK 和 Maven

1. 检查 Docker 环境和用户权限

       确保 Docker 已正确安装,并确保用户在 docker 组中,命令如下:

# 验证 Docker 安装
docker --version

# 如果未安装,可以使用以下命令安装
apt-get update
apt-get install -y docker.io
systemctl enable --now docker

# 检查当前用户是否在 docker 组中
groups
# 如果不在,需要请管理员将您添加到 docker 组
# sudo usermod -aG docker 您的用户名
# 添加后需要重新登录才能生效

        笔者已安装,效果图如下:

2. 创建工作目录结构

        目录结构如下:

# 个人开发环境 目录
~/dev/
  ├── jdk/
  │   ├── jdk-8
  │   ├── jdk-11
  │   └── jdk-17
  ├── maven/
  │   ├── maven-3.6.3
  │   ├── maven-3.8.6
  │   └── maven-3.9.3
  └── docker/ # Docker相关配置


# 系统级 目录
/opt
  ├── jdk/
  └── maven/

        命令如下:

# 以app用户登录执行
mkdir -p ~/dev/jdk/{jdk-8,jdk-11,jdk-17}
mkdir -p ~/dev/maven/{maven-3.6.3,maven-3.8.6,maven-3.9.3}
mkdir -p ~/dev/docker

sudo mkdir -p /opt/jdk /opt/maven
sudo chown app:app /opt/jdk /opt/maven
# 权限 700 表示:所有者(app):可读、可写、可执行;用户组和其他人:无权限
sudo chmod 700 /opt/jdk /opt/maven

3. 创建 Dockerfile 并构建镜像

        在~/dev目录下创建 Dockerfile,进入目录命令如下:

cd ~/dev/docker

3.1. 创建基础 Dockerfile (非最终构建产物)

        先构建基本镜像(JDK、Maven各版本),基于基本镜像构建应用镜像,每个镜像独立维护和更新

        优点:层次清晰,便于维护;可以复用基础镜像;便于版本管理

        缺点:存储空间占用大;构建过程冗长;镜像之间存在重复内容

        示例:创建基础 JDK、Maven 镜像 Dockerfile 文件,命令如下:

cat > Dockerfile.jdk8 << 'EOF'
FROM eclipse-temurin:8-jdk as jdk8
WORKDIR /opt/java
CMD ["java", "-version"]
EOF

cat > Dockerfile.jdk11 << 'EOF'
FROM eclipse-temurin:11-jdk as jdk11
WORKDIR /opt/java
CMD ["java", "-version"]
EOF

cat > Dockerfile.jdk17 << 'EOF'
FROM eclipse-temurin:17-jdk as jdk17
WORKDIR /opt/java
CMD ["java", "-version"]
EOF

cat > Dockerfile.maven363 << 'EOF'
FROM maven:3.6.3-jdk-8 as maven363
WORKDIR /opt/maven
CMD ["mvn", "-version"]
EOF

cat > Dockerfile.maven386 << 'EOF'
FROM maven:3.8.6-eclipse-temurin-11 as maven386
WORKDIR /opt/maven
CMD ["mvn", "-version"]
EOF

cat > Dockerfile.maven393 << 'EOF'
FROM maven:3.9.3-eclipse-temurin-17 as maven393
WORKDIR /opt/maven
CMD ["mvn", "-version"]
EOF

        效果图如下:

        构建基础 JDK、Maven 镜像,命令如下:

# 构建基本镜像
docker build -t dev/jdk8 -f Dockerfile.jdk8 .
docker build -t dev/jdk11 -f Dockerfile.jdk11 .
docker build -t dev/jdk17 -f Dockerfile.jdk17 .

docker build -t dev/maven363 -f Dockerfile.maven363 .
docker build -t dev/maven386 -f Dockerfile.maven386 .
docker build -t dev/maven393 -f Dockerfile.maven393 .

         笔者以jdk8、maven363 为例,正常构建效果图分别如下:

3.2. 创建多阶段构建 Dockerfile (最终构建产物)并构建镜像

        创建一个综合多阶段构建的 Dockerfile.combined,Dockerfile.combined 内容如下:

# JDK stages
FROM eclipse-temurin:8-jdk as jdk8
FROM eclipse-temurin:11-jdk as jdk11
FROM eclipse-temurin:17-jdk as jdk17

# Maven stages
FROM maven:3.6.3-jdk-8 as maven363
FROM maven:3.8.6-eclipse-temurin-11 as maven386
FROM maven:3.9.3-eclipse-temurin-17 as maven393
# 为 maven 添加检查和路径输出
RUN which mvn | xargs dirname | xargs dirname > /maven-path.txt

# Final minimal stage for execution
FROM debian:bullseye-slim as runtime
ARG USER_HOME=/home/app

# Create directories mirroring host structure and set up user
RUN mkdir -p ${USER_HOME}/dev/jdk ${USER_HOME}/dev/maven ${USER_HOME}/bin && \
    groupadd --gid 1000 app && \
    useradd --uid 1000 --gid 1000 --shell /bin/bash --create-home app && \
    chown -R app:app ${USER_HOME}

# Copy JDKs
COPY --from=jdk8 /opt/java ${USER_HOME}/dev/jdk/jdk-8
COPY --from=jdk11 /opt/java ${USER_HOME}/dev/jdk/jdk-11
COPY --from=jdk17 /opt/java ${USER_HOME}/dev/jdk/jdk-17

# Copy Maven
COPY --from=maven363 /usr/share/maven ${USER_HOME}/dev/maven/maven-3.6.3
COPY --from=maven386 /usr/share/maven ${USER_HOME}/dev/maven/maven-3.8.6
COPY --from=maven393 /usr/share/maven ${USER_HOME}/dev/maven/maven-3.9.3

# Set permissions for dev directory
RUN chmod -R 755 ${USER_HOME}/dev

# Create switch script with proper permissions
RUN echo '#!/bin/bash' > ${USER_HOME}/bin/switch.sh && \
    echo '' >> ${USER_HOME}/bin/switch.sh && \
    echo 'switch_jdk() {' >> ${USER_HOME}/bin/switch.sh && \
    echo '    local version=$1' >> ${USER_HOME}/bin/switch.sh && \
    echo '    local jdk_path="${HOME}/dev/jdk/jdk-${version}/openjdk"' >> ${USER_HOME}/bin/switch.sh && \
    echo '' >> ${USER_HOME}/bin/switch.sh && \
    echo '    if [ ! -d "${jdk_path}" ]; then' >> ${USER_HOME}/bin/switch.sh && \
    echo '        echo "错误: JDK ${version} 不存在于 ${jdk_path}" >&2' >> ${USER_HOME}/bin/switch.sh && \
    echo '        return 1' >> ${USER_HOME}/bin/switch.sh && \
    echo '    fi' >> ${USER_HOME}/bin/switch.sh && \
    echo '' >> ${USER_HOME}/bin/switch.sh && \
    echo '    export JAVA_HOME="${jdk_path}"' >> ${USER_HOME}/bin/switch.sh && \
    echo '    local new_path=$(echo $PATH | sed -E "s|:[^:]*jdk[^:]*bin::|:|g")' >> ${USER_HOME}/bin/switch.sh && \
    echo '    export PATH="${JAVA_HOME}/bin:${new_path}"' >> ${USER_HOME}/bin/switch.sh && \
    echo '    echo "已切换到 JDK ${version}: ${jdk_path}"' >> ${USER_HOME}/bin/switch.sh && \
    echo '}' >> ${USER_HOME}/bin/switch.sh && \
    echo '' >> ${USER_HOME}/bin/switch.sh && \
    echo 'switch_maven() {' >> ${USER_HOME}/bin/switch.sh && \
    echo '    local version=$1' >> ${USER_HOME}/bin/switch.sh && \
    echo '    local maven_path="${HOME}/dev/maven/maven-${version}"' >> ${USER_HOME}/bin/switch.sh && \
    echo '' >> ${USER_HOME}/bin/switch.sh && \
    echo '    if [ ! -d "${maven_path}" ]; then' >> ${USER_HOME}/bin/switch.sh && \
    echo '        echo "错误: Maven ${version} 不存在于 ${maven_path}" >&2' >> ${USER_HOME}/bin/switch.sh && \
    echo '        return 1' >> ${USER_HOME}/bin/switch.sh && \
    echo '    fi' >> ${USER_HOME}/bin/switch.sh && \
    echo '' >> ${USER_HOME}/bin/switch.sh && \
    echo '    export MAVEN_HOME="${maven_path}"' >> ${USER_HOME}/bin/switch.sh && \
    echo '    local new_path=$(echo $PATH | sed -E "s|:[^:]*maven[^:]*bin::|:|g")' >> ${USER_HOME}/bin/switch.sh && \
    echo '    export PATH="${MAVEN_HOME}/bin:${new_path}"' >> ${USER_HOME}/bin/switch.sh && \
    echo '    echo "已切换到 Maven ${version}: ${maven_path}"' >> ${USER_HOME}/bin/switch.sh && \
    echo '}' >> ${USER_HOME}/bin/switch.sh && \
    chmod +x ${USER_HOME}/bin/switch.sh && \
    chown app:app ${USER_HOME}/bin/switch.sh

# Create init-env script with proper permissions
RUN echo '#!/bin/bash' > ${USER_HOME}/bin/init-env.sh && \
    echo 'source ${HOME}/bin/switch.sh' >> ${USER_HOME}/bin/init-env.sh && \
    echo 'if [ ! -z "$INIT_JDK" ]; then' >> ${USER_HOME}/bin/init-env.sh && \
    echo '    switch_jdk $INIT_JDK' >> ${USER_HOME}/bin/init-env.sh && \
    echo 'fi' >> ${USER_HOME}/bin/init-env.sh && \
    echo 'if [ ! -z "$INIT_MAVEN" ]; then' >> ${USER_HOME}/bin/init-env.sh && \
    echo '    switch_maven $INIT_MAVEN' >> ${USER_HOME}/bin/init-env.sh && \
    echo 'fi' >> ${USER_HOME}/bin/init-env.sh && \
    echo 'exec "$@"' >> ${USER_HOME}/bin/init-env.sh && \
    chmod +x ${USER_HOME}/bin/init-env.sh && \
    chown app:app ${USER_HOME}/bin/init-env.sh

# Create .bashrc with proper permissions
RUN echo '# .bashrc' > ${USER_HOME}/.bashrc && \
    echo 'export PATH=${HOME}/bin:${PATH}' >> ${USER_HOME}/.bashrc && \
    echo 'source ${HOME}/bin/switch.sh' >> ${USER_HOME}/.bashrc && \
    chown app:app ${USER_HOME}/.bashrc

# Verify script permissions
RUN test -x ${USER_HOME}/bin/init-env.sh && \
    test -x ${USER_HOME}/bin/switch.sh

# Switch to app user
USER app
WORKDIR ${USER_HOME}

# Set PATH
ENV PATH=${USER_HOME}/bin:$PATH

# Set entrypoint
ENTRYPOINT ["/home/app/bin/init-env.sh"]
CMD ["bash"]

         构建镜像,命令如下:

# 构建综合镜像
docker build -t dev/tools -f Dockerfile.combined .

        笔者执行上述命令第一次失败,异常效果图如下:

         配置国内(中国大陆)镜像加速可以解决上述问题,命令如下:

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "data-root": "/data/docker",
  "exec-opts": ["native.cgroupdriver=systemd"],
  "runtimes": {
    "containerd": {
      "path": "/run/containerd/containerd.sock"
    }
  },
  "registry-mirrors": [
    "https://mirror.baidubce.com",
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com",
    "https://mirrors.aliyun.com/docker-ce"
  ]
}
EOF

sudo systemctl daemon-reload
sudo systemctl restart docker

        正常效果图如下:

4. 创建和使用不同版本的脚本

4.1. 创建JDK切换信息显示脚本 docker-use-jdk(可选)

        docker-use-jdk 内容如下:

#!/bin/bash

# 默认值和输入处理
VERSION="$1"
COMMAND="${@:2}"

# 检查版本参数
if [[ ! "$VERSION" =~ ^(8|11|17)$ ]]; then
  echo "Usage: docker-use-jdk [8|11|17] [command]"
  echo "Examples:"
  echo "  docker-use-jdk 8              # 运行Java 8,显示版本"
  echo "  docker-use-jdk 11 java -jar app.jar  # 用Java 11运行JAR文件"
  echo "  docker-use-jdk 17 javac Hello.java   # 用Java 17编译Java文件"
  exit 1
fi

if [ -z "$COMMAND" ]; then
  COMMAND="java -version"
fi

# 获取当前用户的UID和GID
USER_ID=$(id -u)
GROUP_ID=$(id -g)
CURRENT_DIR=$(pwd)

# 确保需要的目录挂载正确,并直接在容器中执行命令
docker run --rm -it \
  -v "$CURRENT_DIR":"$CURRENT_DIR" \
  -w "$CURRENT_DIR" \
  --user $USER_ID:$GROUP_ID \
  dev/tools bash -c "
    # 直接设置Java路径,避免使用可能不存在的脚本
    if [ \"$VERSION\" = \"8\" ]; then
      export JAVA_HOME=/home/app/dev/jdk/jdk-8/openjdk
    elif [ \"$VERSION\" = \"11\" ]; then
      export JAVA_HOME=/home/app/dev/jdk/jdk-11/openjdk
    elif [ \"$VERSION\" = \"17\" ]; then
      export JAVA_HOME=/home/app/dev/jdk/jdk-17/openjdk
    fi
    export PATH=\$JAVA_HOME/bin:\$PATH
    echo \"已切换到 JDK $VERSION: \$JAVA_HOME\"
    $COMMAND
  "

          命令如下: 

# 保存脚本后,确保它有执行权限
chmod +x ~/bin/docker-use-jdk

# 切换 JDK 11 信息
docker-use-jdk 11

        效果图如下:

4.2. 创建Maven切换信息显示脚本 docker-use-maven(可选)

        docker-use-maven 内容如下:

#!/bin/bash

# 默认值和输入处理
MAVEN_VERSION="$1"
JDK_VERSION="$2"
COMMAND="${@:3}"

# 检查版本参数
if [[ ! "$MAVEN_VERSION" =~ ^(3\.6\.3|3\.8\.6|3\.9\.3)$ ]]; then
  echo "Usage: docker-use-maven [3.6.3|3.8.6|3.9.3] [8|11|17] [command]"
  echo "Examples:"
  echo "  docker-use-maven 3.6.3 11            # 运行Maven 3.6.3与JDK 11,显示版本"
  echo "  docker-use-maven 3.8.6 8 mvn clean install  # 用Maven 3.8.6与JDK 8运行构建"
  exit 1
fi

# 检查JDK版本
if [[ ! "$JDK_VERSION" =~ ^(8|11|17)$ ]]; then
  # 使用默认的JDK 11
  JDK_VERSION="11"
fi

if [ -z "$COMMAND" ]; then
  COMMAND="mvn -version"
fi

# 获取当前用户的UID和GID
USER_ID=$(id -u)
GROUP_ID=$(id -g)
CURRENT_DIR=$(pwd)

# 运行对应版本的Maven容器,同时设置JDK
docker run --rm -it \
  -v "$CURRENT_DIR":"$CURRENT_DIR" \
  -v "$HOME/.m2":/home/app/.m2 \
  -w "$CURRENT_DIR" \
  --user $USER_ID:$GROUP_ID \
  dev/tools bash -c "source /home/app/bin/switch.sh && switch_jdk $JDK_VERSION && switch_maven $MAVEN_VERSION && $COMMAND"

        命令如下: 

# 保存脚本后,确保它有执行权限
chmod +x ~/bin/docker-use-maven

# 切换 Maven 3.8.6 信息
docker-use-maven 3.8.6

         效果图如下:

4.3. 创建一个综合开发环境脚本 dev-env

        dev-env 文件内容如下:

#!/bin/bash

# 默认值
JDK_VERSION="8"
MAVEN_VERSION="3.6.3"
MODE="interactive" # interactive 或 run 模式
COMMAND=""
DOCKER_EXTRA_ARGS=""

# 获取当前用户的UID和GID
USER_ID=$(id -u)
GROUP_ID=$(id -g)
CURRENT_DIR=$(pwd)

# 函数:打印帮助信息
print_help() {
    echo "用法: dev-env [选项] [-- 命令]"
    echo ""
    echo "选项:"
    echo "  -j, --jdk VERSION     指定JDK版本 (默认: 8)"
    echo "  -m, --maven VERSION   指定Maven版本 (默认: 3.6.3)"
    echo "  -d, --docker-args ARGS 传递额外参数给docker run"
    echo "  -h, --help            显示此帮助信息"
    echo ""
    echo "命令示例:"
    echo "  dev-env                         # 启动带有默认JDK 8和Maven 3.6.3的交互式bash"
    echo "  dev-env -j 11 -m 3.8.6          # 启动带有JDK 11和Maven 3.8.6的交互式bash"
    echo "  dev-env -j 17 -- mvn clean install  # 在JDK 17环境中执行mvn clean install"
    echo "  dev-env -- java -version        # 运行java -version命令并退出"
    echo "  dev-env -d \"-p 8080:8080\"      # 启动带有端口映射的环境"
}

# 解析命令行参数
while [[ $# -gt 0 ]]; do
    case $1 in
        -h|--help)
            print_help
            exit 0
            ;;
        -j|--jdk)
            if [[ $# -gt 1 ]]; then
                JDK_VERSION="$2"
                shift 2
            else
                echo "错误: JDK版本参数缺失" >&2
                exit 1
            fi
            ;;
        -m|--maven)
            if [[ $# -gt 1 ]]; then
                MAVEN_VERSION="$2"
                shift 2
            else
                echo "错误: Maven版本参数缺失" >&2
                exit 1
            fi
            ;;
        -d|--docker-args)
            if [[ $# -gt 1 ]]; then
                DOCKER_EXTRA_ARGS="$2"
                shift 2
            else
                echo "错误: Docker参数缺失" >&2
                exit 1
            fi
            ;;
        --)
            shift
            MODE="run"
            COMMAND="$*"
            break
            ;;
        *)
            echo "错误: 未知选项 $1" >&2
            print_help
            exit 1
            ;;
    esac
done

# 运行容器 - 修复引号和路径问题
if [[ "$MODE" == "run" ]]; then
    # 运行模式
    docker run --rm -it \
      -v "$CURRENT_DIR":"$CURRENT_DIR" \
      -v "$HOME/.m2":/home/app/.m2 \
      -w "$CURRENT_DIR" \
      --user $USER_ID:$GROUP_ID \
      -e INIT_JDK="$JDK_VERSION" \
      -e INIT_MAVEN="$MAVEN_VERSION" \
      $DOCKER_EXTRA_ARGS \
      dev/tools $COMMAND
else
    # 交互式bash模式
    docker run --rm -it \
      -v "$CURRENT_DIR":"$CURRENT_DIR" \
      -v "$HOME/.m2":/home/app/.m2 \
      -w "$CURRENT_DIR" \
      --user $USER_ID:$GROUP_ID \
      -e INIT_JDK="$JDK_VERSION" \
      -e INIT_MAVEN="$MAVEN_VERSION" \
      $DOCKER_EXTRA_ARGS \
      dev/tools bash
fi

        命令如下: 

# 保存脚本后,确保它有执行权限
chmod +x ~/bin/dev-env

# 添加PATH并使脚本可用
echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

# 使用Maven 3.8.6和JDK 11
dev-env -j 11 -m 3.8.6

        效果图如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值