如何使用 python 和 Java 运行 Docker?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/51121875/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 23:57:49  来源:igfitidea点击:

How to run Docker with python and Java?

javapythonpython-3.xdocker

提问by pajamas

I need both java and python in my docker container to run some code.

我的 docker 容器中需要 java 和 python 来运行一些代码。

This is my dockerfile: It works perpectly if I don't add the FROM openjdk:slim

这是我的 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"]

And the test.py app is in the same directory:

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)

I'm getting this error:

我收到此错误:

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.

What exactly am I doing wrong here? I'm new to docker, perhaps I'm missing a step.

我到底做错了什么?我是 docker 新手,也许我错过了一步。

Additional details

额外细节

My goal

我的目标

I have to run a python program that runs a Java file. The python library I'm using requires the path to JAVA_HOME.

我必须运行一个运行 Java 文件的 python 程序。我正在使用的 python 库需要JAVA_HOME.

My issues:

我的问题:

  • I do not know Java, so I cannot run the file properly.

  • My entire code is in Python, except this Java bit

  • The Python wrapper runs the file in a way I need it to run.

  • 我不会 Java,因此无法正确运行该文件。

  • 我的整个代码都是用 Python 写的,除了这个 Java 位

  • Python 包装器以我需要它运行的方式运行文件。

采纳答案by pajamas

OK it took me a little while to figure it out. And my thanks go to this answer.

好吧,我花了一点时间才弄明白。我感谢这个答案

I think my approach didn't work because I did not have a basic version of Linux.

我认为我的方法不起作用,因为我没有 Linux 的基本版本。

So it goes like this:

所以它是这样的:

  1. Get Linux (I'm using Alpine because it's barebones)
  2. Get Java via the package manager
  3. Get Python, PIP
  1. 获取 Linux(我使用 Alpine,因为它是准系统)
  2. 通过包管理器获取 Java
  3. 获取 Python、PIP

OPTIONAL: find and set JAVA_HOME

可选:查找并设置 JAVA_HOME

  1. Find the path to JAVA_HOME. Perhaps there is a better way to do this, but I did this running the running the container, then I looked inside the container using docker exec -it [COINTAINER ID] bin/bashand found it.
  2. Set JAVA_HOMEin dockerfile and build + run it all again
  1. 找到 JAVA_HOME 的路径。也许有更好的方法可以做到这一点,但是我在运行容器时这样做了,然后我使用容器内部查看 docker exec -it [COINTAINER ID] bin/bash并找到了它。
  2. JAVA_HOME在 dockerfile 中设置并构建 + 再次运行它

Here is the final Dockerfile ( it should work with the python code in the question) :

这是最终的 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"]

I'm new to Docker, so this may not be the best possible solution. I'm open to suggestions.

我是 Docker 的新手,所以这可能不是最好的解决方案。我愿意接受建议。

回答by Simas Joneliunas

I believe that by adding FROM openjdk:slimline, you tell docker to execute all of your subsequent commands in openjdk container (which does not have python)

我相信通过添加FROM openjdk:slim行,您可以告诉 docker 在 openjdk 容器(没有 python)中执行所有后续命令

I would approach this by creating two separate containers for openjdk and python and specify individual sets of commands for them.

我会通过为 openjdk 和 python 创建两个单独的容器并为它们指定单独的命令集来解决这个问题。

Docker is made to modularize your solutions and mashing everything into one container is usually a bad practice.

Docker 旨在模块化您的解决方案,将所有内容混合到一个容器中通常是一种不好的做法。

回答by Hemant Singh

Instead of using FROM openjdk:slimyou can separately install Java, please refer below example:

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

回答by RELW

you should have one FROM in your dockerfile (unless you use multi-stage build for the docker)

您的 dockerfile 中应该有一个 FROM(除非您对 docker 使用多阶段构建)

回答by Yan Khonski

Oh, let me add my five cents. I took python slim as a base image. Then I found open-jdk-11 (Note, open-jdk-10 will fail because it is not supported) base image code!... And copy-pasted it into my docker file.

哦,让我加上我的五美分。我将 python slim 作为基本图像。然后我找到了 open-jdk-11(注意,open-jdk-10 将失败,因为它不受支持)基本图像代码!...并将其复制粘贴到我的 docker 文件中。

Note, copy-paste driven developmentis cool... ONLY when you understand each line you use in your code!!!

注意,复制粘贴驱动的开发很酷……只有当你理解你在代码中使用的每一行时!!!

And here it is!

就在这里!

<!-- 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"

Now references. https://github.com/AdoptOpenJDK/openjdk-docker/blob/master/11/jdk/ubuntu/Dockerfile.hotspot.releases.slim

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

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

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

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

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

I used them to answer this question, which may help you sometime. Running Python and Java in Docker

我用它们来回答这个问题,它可能在某个时候对你有所帮助。 在 Docker 中运行 Python 和 Java

回答by Sunny Pal

An easier solution to the above issue is to use multi-stage docker containers where you can copy the content from one to another. In the above case you can have openjdk:slimas the base container and then use content from a python container to be copied over into this base container as follows:

上述问题的一个更简单的解决方案是使用多阶段 docker 容器,您可以在其中将内容从一个复制到另一个。在上述情况下,您可以openjdk:slim将基础容器作为基础容器,然后使用 python 容器中的内容复制到该基础容器中,如下所示:

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

... 

<normal instructions for python container continues>

...

This feature is available as of Docker 17.05 and there are more things you can do using multi-stage build as in copying only the content you need from one to another.

此功能从 Docker 17.05 开始可用,您可以使用多阶段构建执行更多操作,例如仅将您需要的内容从一个复制到另一个。

Reference documentation

参考文档

回答by Juliusz Ry?ko

Another alternative is to simply use docker-java-python imagefrom docker hub. https://hub.docker.com/r/rappdw/docker-java-python

另一种选择是简单地使用来自 docker hub 的docker-java-python 图像https://hub.docker.com/r/rappdw/docker-java-python

FROM rappdw/docker-java-python:openjdk1.8.0_171-python3.6.6
RUN java -version
RUN python --version