简体   繁体   English

如何使用 scl enable 在 dockerfile 中运行 python3 应用程序

[英]How to use scl enable to run python3 app in dockerfile

Im trying to run a python3 application in a docker container using CentOS 7 as the base image.我尝试使用 CentOS 7 作为基本映像在 docker 容器中运行 python3 应用程序。 So if I'm just playing with it interactively, I type scl enable rh-python36 bash所以如果我只是以交互方式玩它,我输入scl enable rh-python36 bash

That obviously switches my standard python2 environment to the python3.6 environment I install earlier(in the Dockerfile) Now, earlier in the dockerfile I run the following:这显然将我的标准 python2 环境切换到我之前安装的 python3.6 环境(在 Dockerfile 中)现在,在 dockerfile 中我运行以下命令:

SHELL ["scl", "enable", "rh-python36"] (and many variations of this) SHELL ["scl", "enable", "rh-python36"] (以及许多变体)

This enables me to do all of my pip installations in this python3 environment.这使我能够在这个 python3 环境中完成我所有的 pip 安装。 However, when I actually want to run my app.py with CMD, it defaults to the python2.但是,当我真的想用 CMD 运行我的 app.py 时,它默认为 python2.py 。 I've tried playing with ENTRYPOINT and variations of CMD, but I cant seem to make the python3 environment active when the container finally runs.我已经尝试使用 ENTRYPOINT 和 CMD 的变体,但是当容器最终运行时,我似乎无法激活 python3 环境。 How can I get this running correctly with python3?如何使用python3正确运行它?

Here's the dockerfile:这是 dockerfile:

FROM centos:7
RUN mkdir -p /usr/src/app && \
  yum install -y centos-release-scl && \
  yum install -y rh-python36 && \
  yum install -y rh-python36-python-tkinter
SHELL ["scl", "enable", "rh-python36"]
WORKDIR /usr/src/app
COPY . .
WORKDIR /usr/src/app/codeBase
RUN pip install --no-cache-dir -r /usr/src/app/codeBase/requirements.txt
EXPOSE 9000
CMD ["python",  "run.py"]

I've also tried the alias solution, but I'm afraid it doesnt change the python exe for the CMD: Here's the totally runnable version with that that still prints out python 2.7.5:我也试过别名解决方案,但恐怕它不会改变 CMD 的 python exe:这是完全可运行的版本,它仍然打印出 python 2.7.5:

FROM centos:7
RUN mkdir -p /usr/src/app && \  
  yum install -y centos-release-scl && \
  yum install -y rh-python36 && \
  yum install -y rh-python36-python-tkinter
WORKDIR /usr/src/app
RUN alias python=$(find / -type f -name "python*" | grep "python3.6$")
CMD ["python",  "-V"]

It just seems as though none of this persists in the new shell created with CMD似乎这些都不会在用 CMD 创建的新 shell 中持续存在

SHELL is completely the wrong Dockerfile command for this. SHELL完全是错误的Dockerfile命令。 You'll probably want to put that in a RUN stanza instead. 您可能需要将其放在RUN节中。

The purpose of SHELL is to define the shell used to execute RUN commands. SHELL的目的是定义用于执行RUN命令的外壳。 So something like 所以像

SHELL ["sh", "-c"] # The default
RUN echo "foo"

ends up running 最终运行

sh -c 'echo "foo"'

Of course, replacing SHELL with a command which doesn't support this use case will simply break the RUN command for you. 当然,用不支持此用例的命令替换SHELL只会为您破坏RUN命令。

Maybe try something like 也许尝试像

FROM centos:7
RUN mkdir -p /usr/src/app && \
  yum install -y centos-release-scl && \
  yum install -y rh-python36 && \
  yum install -y rh-python36-python-tkinter
WORKDIR /usr/src/app
COPY . .
WORKDIR /usr/src/app/codeBase
RUN scl enable rh-python36 pip install --no-cache-dir -r ./requirements.txt
EXPOSE 9000
CMD ["scl", "enable", "rh-python36", "python",  "run.py"]

Note: 注意:

I am leaving this answer up as context to the question, but this does not solve the issue. 我要离开这个答案最多为背景的问题,但这并不解决问题。 My attempt was to modify where python is pointing, but if executing in a RUN command, the shell will exit and you'll lose the alias . 我的尝试是修改python指向的位置,但是如果在RUN命令中执行,shell将退出并且您将失去alias Modifying the PYTHONPATH via bash is also a no-go, per this question . 对于这个问题 ,通过bash修改PYTHONPATH也是PYTHONPATH Thanks to @tripleee for the catch 感谢@tripleee的帮助

Unfortunately, it looks like yum install -y rh-python36 puts that python3.6 in a really weird spot: 不幸的是,它看起来像yum install -y rh-python36将python3.6放在一个非常奇怪的地方:

find / -type f -name "python*" | grep "python3.6$"
/opt/rh/rh-python36/root/usr/bin/python3.6

You can use that to alias your python command in your Dockerfile : 您可以使用它在Dockerfile python命令添加alias

RUN mkdir -p /usr/src/app && \
  yum install -y centos-release-scl && \
  yum install -y rh-python36 && \
  yum install -y rh-python36-python-tkinter

# Here
RUN alias python=$(find / -type f -name "python*" | grep "python3.6$")

Which should allow you to retain your CMD and also ties it to the correct site-packages : 这应该可以让您保留您的CMD并将其与正确的site-packages

import sys

sys.path
['', '/opt/rh/rh-python36/root/usr/lib64/python36.zip', '/opt/rh/rh-python36/root/usr/lib64/python3.6', '/opt/rh/rh-python36/root/usr/lib64/python3.6/lib-dynload', '/opt/rh/rh-python36/root/usr/lib64/python3.6/site-packages', '/opt/rh/rh-python36/root/usr/lib/python3.6/site-packages']

It looks like this also might remove the need to scl enable that python environment, as you can then just use python -m pip... : 看起来这也可能消除了scl enable该python环境的需要,因为您可以仅使用python -m pip...

# No scl has been run
python -m pip install requests
# running python in the terminal
import requests

r = requests.get('http://google.com')
# runs like a charm

So I figured this out thanks to the answer from C.Nivs and an answer here . 因此,我想出了这一点,这要归功于C.Nivs的回答和这里的回答。 The alias works in an interactive shell, but not for the CMD. 别名在交互式外壳中起作用,但不适用于CMD。 What I ended up doing was similar, only in my case I'm creating a new executable in /usr/bin that calls the special python36 exe: 我最终所做的事情是相似的,只是在我的情况下,我在/ usr / bin中创建了一个新的可执行文件,调用了特殊的python36 exe:

RUN echo -e '#!/bin/bash\n$(find / -type f -name "python*" | grep "python3.6$") "$@"' > /usr/bin/py3 && \
    chmod +x /usr/bin/py3
CMD ["py3",  "-V"]

now py3 runs a script calling the python3 install specifically with whatever argument 现在py3运行一个脚本,专门使用任何参数调用python3 install

Configuring the shell environment variables by overriding them all to use scl_source, as seen from following "Method #2" from Austin Dewey's blog works for me.通过覆盖所有 shell 环境变量以使用 scl_source 来配置 shell 环境变量,从 Austin Dewey 的博客中的“方法 #2”可以看出对我有用。

FROM centos:7
SHELL ["/usr/bin/env", "bash", "-c"]
RUN \
    yum install -y centos-release-scl && \
    yum install -y rh-python38-python-devel
ENV \
    BASH_ENV="/usr/bin/scl_enable" \
    ENV="/usr/bin/scl_enable" \
    PROMPT_COMMAND=". /usr/bin/scl_enable"
RUN echo -e "\n\
unset BASH_ENV PROMPT_COMMAND ENV\n\
source scl_source enable rh-python38\n\
" > /usr/bin/scl_enable
RUN \
    python3 -m ensurepip && \
    python3 -m pip install --upgrade pip && \
    python3 -m pip install setuptools wheel
docker build --tag python:3.8-test - < Dockerfile
docker run --rm -i -t python:3.8-test
python --version

Python 3.8.11蟒蛇 3.8.11

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM