如何使用 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
How to run Docker with python and Java?
提问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:
所以它是这样的:
- Get Linux (I'm using Alpine because it's barebones)
- Get Java via the package manager
- Get Python, PIP
- 获取 Linux(我使用 Alpine,因为它是准系统)
- 通过包管理器获取 Java
- 获取 Python、PIP
OPTIONAL: find and set JAVA_HOME
可选:查找并设置 JAVA_HOME
- 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/bash
and found it. - Set
JAVA_HOME
in dockerfile and build + run it all again
- 找到 JAVA_HOME 的路径。也许有更好的方法可以做到这一点,但是我在运行容器时这样做了,然后我使用容器内部查看
docker exec -it [COINTAINER ID] bin/bash
并找到了它。 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:slim
line, 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:slim
you 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://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:slim
as 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 开始可用,您可以使用多阶段构建执行更多操作,例如仅将您需要的内容从一个复制到另一个。
回答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