Как запустить Docker с помощью python и Java?
Мне нужно как java, так и python в моем контейнере докеров, чтобы запустить некоторый код.
Это мой файл докеров: он работает, если я не добавляю 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.
Что именно я делаю неправильно здесь? Я новичок в докере, возможно, мне не хватает шага.
Дополнительные детали
Моя цель
Я должен запустить программу python, которая запускает файл Java. Для используемой библиотеки python требуется путь к JAVA_HOME
.
Мои проблемы:
-
Я не знаю Java, поэтому я не могу запустить файл должным образом.
-
Весь мой код находится в Python, кроме этого Java-бит
-
Оболочка Python запускает файл так, как мне нужно, чтобы он запускался.
Ответы
Ответ 1
ОК, мне потребовалось немного времени, чтобы понять это. И я благодарю этого ответа.
Я думаю, что мой подход не сработал, потому что у меня не было базовой версии Linux.
Так оно и происходит:
- Получите Linux (я использую Alpine, потому что это barebones)
- Получить Java через диспетчер пакетов
- Получить Python, PIP
ДОПОЛНИТЕЛЬНО: найдите и установите JAVA_HOME
- Найдите путь к JAVA_HOME. Возможно, есть лучший способ сделать это, но я выполнил запуск контейнера, затем я заглянул внутрь контейнера, используя
docker exec -it [COINTAINER ID] bin/bash
и нашел его. - Установите
JAVA_HOME
в файл docker и создайте + снова запустите его
Вот окончательный файл Docker (он должен работать с кодом 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, так что это может быть не лучшее решение. Я открыт для предложений.
Ответ 2
О, позвольте мне добавить мои пять центов. Я взял 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 в Docker
Ответ 3
вы должны иметь один ОТ в вашем файле докеров (если вы не используете многоэтапную сборку для докера)
Ответ 4
Я считаю, что, добавив FROM openjdk:slim
line, вы скажете докеру выполнить все ваши последующие команды в контейнере openjdk (у которого нет python)
Я бы подошел к этому, создав два отдельных контейнера для openjdk и python и задав для них отдельные команды.
Docker создан для модулизации ваших решений, и все же мытье в один контейнер - это, как правило, плохая практика.
Ответ 5
Вместо использования 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
Ответ 6
Более простым решением вышеуказанной проблемы является использование многоэтапных док-контейнеров, где вы можете копировать содержимое из одного в другой. В приведенном выше случае вы можете использовать openjdk:slim
в качестве базового контейнера, а затем использовать содержимое из контейнера Python для копирования в этот базовый контейнер следующим образом:
FROM openjdk:slim
COPY --from=python:3.6 / /
...
<normal instructions for python container continues>
...
Эта функция доступна в Docker 17.05, и с помощью многоэтапной сборки вы можете сделать больше вещей, например, копируя только необходимое содержимое из одного в другое.
Справочная документация