【问题标题】:sdkman does not install java in a dockerfilesdkman 不在 dockerfile 中安装 java
【发布时间】:2019-08-30 21:06:22
【问题描述】:

我有这个 docker 文件:

# We are going to star from the jhipster image
FROM jhipster/jhipster

# install as root
USER root

### Setup docker cli (don't need docker daemon) ###
# Install some packages
RUN apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common -y

# Add Dockers official GPG key:
RUN ["/bin/bash", "-c", "set -o pipefail && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -"]

# Add a stable repository
RUN add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

# Setup aws credentials as environment variables
ENV AWS_ACCESS_KEY_ID "change it!"
ENV AWS_SECRET_ACCESS_KEY "change it!"

# noninteractive install for tzdata
ARG DEBIAN_FRONTEND=noninteractive

# set timezone for tzdata
ENV TZ=America/Sao_Paulo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# Install the latest version of Docker Engine - Community and also aws cli
RUN apt-get update && apt-get install docker-ce docker-ce-cli containerd.io awscli -y

# change back to default user
USER jhipster

# install skd and java version 1.8
RUN curl -s "https://get.sdkman.io" | bash
RUN bash $HOME/.sdkman/bin/sdkman-init.sh
RUN bash -c "sdk install java 8.0.222.j9-adpt"

当我运行命令从这个 dockerfile 构建映像时,它在最后一步失败并显示一条消息:

/bin/sh: 1: sdk: not found

当我在本地机器上安装它时,它会在 bash 上运行 sdkman (sdk)。但是在这个脚本上,它从 sh 而不是 bash 调用它。我怎样才能让它从sh调用skdman(sdk)?我真正想做的是通过sdkman(sdk)安装一个特定的java版本。还有其他方法吗?

【问题讨论】:

    标签: dockerfile sh sdkman


    【解决方案1】:

    要使 sdk 命令可用,您需要运行 source sdkman-init.sh

    这是一个在 centos 上使用 java 11 的工作示例。

    FROM centos:latest
    
    ARG CANDIDATE=java
    ARG CANDIDATE_VERSION=11.0.6-open
    
    ENV SDKMAN_DIR=/root/.sdkman
    
    # update the image
    RUN yum -y upgrade
    
    # install requirements, install and configure sdkman
    # see https://sdkman.io/usage for configuration options
    RUN yum -y install curl ca-certificates zip unzip openssl which findutils && \
        update-ca-trust && \
        curl -s "https://get.sdkman.io" | bash && \
        echo "sdkman_auto_answer=true" > $SDKMAN_DIR/etc/config && \
        echo "sdkman_auto_selfupdate=false" >> $SDKMAN_DIR/etc/config
    
    # Source sdkman to make the sdk command available and install candidate
    RUN bash -c "source $SDKMAN_DIR/bin/sdkman-init.sh && sdk install $CANDIDATE $CANDIDATE_VERSION"
    
    # Add candidate path to $PATH environment variable
    ENV JAVA_HOME="$SDKMAN_DIR/candidates/java/current"
    ENV PATH="$JAVA_HOME/bin:$PATH"
    
    ENTRYPOINT ["/bin/bash", "-c", "source $SDKMAN_DIR/bin/sdkman-init.sh && \"$@\"", "-s"]
    CMD ["sdk", "help"]
    

    【讨论】:

    • 虽然它应该可以工作,但我不确定"-s"ENTRYPOINT 中是否正确。我认为它只是弥补了$@ 跳过第一个参数(在这种情况下为sdk)。因此,"\"${@:0}\"" 可以在没有 , "-s" 的情况下使用
    【解决方案2】:

    问题是 Dockerfile 中的每个 RUN 命令都是在新的 bash 环境中执行的,因此您需要将最后两个命令放在同一行下,如下所示:

    RUN bash $HOME/.sdkman/bin/sdkman-init.sh && bash -c "sdk install java 8.0.222.j9-adpt"

    【讨论】: