web-dev-qa-db-ja.com

pythonとJavaでDockerを実行するには?

何らかのコードを実行するには、DockerコンテナにJavaとpythonの両方が必要です。

これは私のdockerfileです:FROM openjdk:slimを追加しなくても正常に動作します

#get python
FROM python:3.6-slim

RUN pip install --trusted-Host pypi.python.org flask

#get openjdk

FROM openjdk:slim


COPY . /targetdir
WORKDIR /targetdir

# Make port 81 available to the world outside this container
EXPOSE 81

CMD ["python", "test.py"]

そして、test.pyアプリは同じディレクトリにあります。

from flask import Flask

import os
app = Flask(__name__)


@app.route("/")

def hello():
    html = "<h3>Test:{test}</h3>"
    test = os.environ['Java_HOME']

    return html.format(test = test)


if __name__ == '__main__':
    app.run(debug=True,Host='0.0.0.0',port=81)

私はこのエラーを受け取っています:

D:\MyApps\Docker Toolbox\Docker Toolbox\docker.exe: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"python\": executable file not found in $PATH": unknown.

ここで何が間違っていますか?私はdockerを初めて使用します。おそらく、ステップがありません。

追加の詳細

私の目標

pythonファイルを実行するJavaプログラムを実行する必要があります。使用しているpythonライブラリには、Java_HOMEへのパスが必要です。

私の問題:

  • Javaがわからないため、ファイルを適切に実行できません。

  • このJavaビットを除いて、私のコード全体はPythonです。

  • Pythonラッパーは、実行に必要な方法でファイルを実行します。

11
pajamas

OKそれを理解するのに少し時間がかかりました。そして、これに感謝します answer

Linuxの基本バージョンを持っていなかったため、私のアプローチはうまくいかなかったと思います。

したがって、次のようになります。

  1. Linuxを入手します(私はAlpineを使用しています)
  2. Get Javaパッケージマネージャー経由
  3. Python、PIPを入手する

[〜#〜] optional [〜#〜]:Java_HOMEを見つけて設定する

  1. Java_HOMEへのパスを見つけます。おそらくこれを行うためのより良い方法がありますが、コンテナを実行してこれを実行し、docker exec -it [COINTAINER ID] bin/bashを使用してコンテナ内を調べて見つけました。
  2. DockerfileでJava_HOMEを設定し、ビルドしてもう一度実行します

最終的なDockerfileは次のとおりです(問題のpythonコードで動作するはずです):

### 1. Get Linux
FROM Alpine:3.7

### 2. Get Java via the package manager
RUN apk update \
&& apk upgrade \
&& apk add --no-cache bash \
&& apk add --no-cache --virtual=build-dependencies unzip \
&& apk add --no-cache curl \
&& apk add --no-cache openjdk8-jre

### 3. Get Python, PIP

RUN apk add --no-cache python3 \
&& python3 -m ensurepip \
&& pip3 install --upgrade pip setuptools \
&& rm -r /usr/lib/python*/ensurepip && \
if [ ! -e /usr/bin/pip ]; then ln -s pip3 /usr/bin/pip ; fi && \
if [[ ! -e /usr/bin/python ]]; then ln -sf /usr/bin/python3 /usr/bin/python; fi && \
rm -r /root/.cache

### Get Flask for the app
RUN pip install --trusted-Host pypi.python.org flask

####
#### OPTIONAL : 4. SET Java_HOME environment variable, uncomment the line below if you need it

#ENV Java_HOME="/usr/lib/jvm/Java-1.8-openjdk"

####

EXPOSE 81    
ADD test.py /
CMD ["python", "test.py"]

私はDockerが初めてなので、これが最良の解決策ではないかもしれません。私は提案を受け入れます。

12
pajamas

ああ、私は私の5セントを追加します。 python slimをベースイメージとして使用しました。その後、open-jdk-11が見つかりました(サポートされていないため、open-jdk-10は失敗します)ベースイメージコード!...そしてDockerファイルにコピーアンドペーストしました。

注、コピーアンドペースト駆動開発はクールです...コードで使用する各行を理解している場合のみ!!!

そしてここにある!

<!-- language: Shell -->
FROM python:3.7.2-slim

# Do your stuff, install python.

# and now Jdk
RUN rm -rf /var/lib/apt/lists/* && apt-get clean && apt-get update && apt-get upgrade -y \
    && apt-get install -y --no-install-recommends curl ca-certificates \
    && rm -rf /var/lib/apt/lists/*

ENV Java_VERSION jdk-11.0.2+7

COPY slim-Java* /usr/local/bin/

RUN set -eux; \
    Arch="$(dpkg --print-architecture)"; \
    case "${Arch}" in \
       ppc64el|ppc64le) \
         ESUM='c18364a778b1b990e8e62d094377af48b000f9f6a64ec21baff6a032af06386d'; \
         BINARY_URL='https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.1%2B13/OpenJDK11U-jdk_ppc64le_linux_hotspot_11.0.1_13.tar.gz'; \
         ;; \
       s390x) \
         ESUM='e39aacc270731dadcdc000aaaf709adae7a08113ccf5b4a045bc87fc13458d71'; \
         BINARY_URL='https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11%2B28/OpenJDK11-jdk_s390x_linux_hotspot_11_28.tar.gz'; \
         ;; \
       AMD64|x86_64) \
         ESUM='d89304a971e5186e80b6a48a9415e49583b7a5a9315ba5552d373be7782fc528'; \
         BINARY_URL='https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.2%2B7/OpenJDK11U-jdk_x64_linux_hotspot_11.0.2_7.tar.gz'; \
         ;; \
       aarch64|arm64) \
         ESUM='b66121b9a0c2e7176373e670a499b9d55344bcb326f67140ad6d0dc24d13d3e2'; \
         BINARY_URL='https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.1%2B13/OpenJDK11U-jdk_aarch64_linux_hotspot_11.0.1_13.tar.gz'; \
         ;; \
       *) \
         echo "Unsupported Arch: ${Arch}"; \
         exit 1; \
         ;; \
    esac; \
    curl -Lso /tmp/openjdk.tar.gz ${BINARY_URL}; \
    sha256sum /tmp/openjdk.tar.gz; \
    mkdir -p /opt/Java/openjdk; \
    cd /opt/Java/openjdk; \
    echo "${ESUM}  /tmp/openjdk.tar.gz" | sha256sum -c -; \
    tar -xf /tmp/openjdk.tar.gz; \
    jdir=$(dirname $(dirname $(find /opt/Java/openjdk -name javac))); \
    mv ${jdir}/* /opt/Java/openjdk; \
    export PATH="/opt/Java/openjdk/bin:$PATH"; \
    apt-get update; apt-get install -y --no-install-recommends binutils; \
    /usr/local/bin/slim-Java.sh /opt/Java/openjdk; \
    apt-get remove -y binutils; \
    rm -rf /var/lib/apt/lists/*; \
    rm -rf ${jdir} /tmp/openjdk.tar.gz;

ENV Java_HOME=/opt/Java/openjdk \
    PATH="/opt/Java/openjdk/bin:$PATH"
ENV Java_TOOL_OPTIONS="-XX:+UseContainerSupport"

今参照。 https://github.com/AdoptOpenJDK/openjdk-docker/blob/master/11/jdk/ubuntu/Dockerfile.hotspot.releases.slim

https://hub.docker.com/_/python/

https://hub.docker.com/r/adoptopenjdk/openjdk11/

私はそれらをこの質問に答えるために使用しました。 実行中PythonおよびJava

2
Yan Khonski

dockerfileにFROMが1つ必要です(dockerにマルチステージビルドを使用する場合を除く)

1
RELW

FROM openjdk:slim行を追加することで、dockerにopenjdkコンテナ(Pythonを持たない)で後続のコマンドをすべて実行するように指示すると思います

Openjdkとpythonの2つの個別のコンテナを作成し、それらに個別のコマンドセットを指定することで、これにアプローチします。

Dockerはソリューションをモジュール化するために作られており、通常はすべてを1つのコンテナーにマッシュすることは悪い習慣です。

0

FROM openjdk:slimを使用する代わりに、Javaを個別にインストールできます。以下の例を参照してください。

# Install OpenJDK-8
RUN apt-get update && \
apt-get install -y openjdk-8-jdk && \
apt-get install -y ant && \
apt-get clean;

# Fix certificate issues
RUN apt-get update && \
apt-get install ca-certificates-Java && \
apt-get clean && \
update-ca-certificates -f;
# Setup Java_HOME -- useful for docker commandline
ENV Java_HOME /usr/lib/jvm/Java-8-openjdk-AMD64/
RUN export Java_HOME
0
Hemant Singh

上記の問題に対するより簡単な解決策は、コンテンツを相互にコピーできるマルチステージドッカーコンテナーを使用することです。上記の場合、openjdk:slimをベースコンテナとして使用し、次にpythonコンテナのコンテンツを使用して、次のようにこのベースコンテナにコピーします。

FROM openjdk:slim
COPY --from=python:3.6 / /

... 

<normal instructions for python container continues>

...

この機能はDocker 17.05から利用でき、必要なコンテンツのみを別のコンテンツにコピーするなど、マルチステージビルドを使用してできることは他にもあります。

リファレンスドキュメント

0
Sunny Pal