如何使用scl enable在dockerfile

时间:2019-06-03 21:36:09

标签: python python-3.x docker dockerfile

我正在尝试使用CentOS 7作为基本映像在docker容器中运行python3应用程序。因此,如果我只是交互式地玩,请输入scl enable rh-python36 bash

显然,这将我的标准python2环境切换到了我先前安装(在Dockerfile中)的python3.6环境中。现在,较早地在dockerfile中,我运行以下命令:

SHELL ["scl", "enable", "rh-python36"](及其许多变体)

这使我能够在python3环境中进行所有的pip安装。但是,当我实际上要使用CMD运行我的app.py时,它默认为python2。我尝试过ENTRYPOINT和CMD的变体,但是当容器最终运行时,我似乎无法使python3环境处于活动状态。如何使用python3使其正常运行?

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

我也尝试过别名解决方案,但恐怕它不会更改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"]

似乎所有这些都不存在于使用CMD创建的新外壳中

3 个答案:

答案 0 :(得分:2)

SHELL完全是错误的Dockerfile命令。您可能需要将其放在RUN节中。

SHELL的用途是定义用于执行RUN命令的外壳。所以像

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

结束运行

sh -c 'echo "foo"'

当然,用不支持此用例的命令替换SHELL只会为您中断RUN命令。

也许可以尝试

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

答案 1 :(得分:1)

注意:

我将这个答案留给问题的背景,但这并不能解决问题。我的尝试是修改python指向的位置,但是如果在RUN命令中执行,shell将退出并且您将丢失alias。根据{{​​3}},通过bash修改PYTHONPATH也是不可行的。感谢@tripleee抓住了机会

不幸的是,看起来yum install -y rh-python36确实把python3.6放在了一个很奇怪的地方:

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

您可以将其用于alias中的python命令{}:

Dockerfile

应该允许您保留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$") 并将其与正确的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'] 那个python环境,因为您可以只使用scl enable

python -m pip...
# No scl has been run
python -m pip install requests

答案 2 :(得分:1)

因此,由于C.Nivs的回答和答案here,我才得以解决。别名在交互式外壳中起作用,但不适用于CMD。我最终所做的事情是相似的,只是在我的情况下,我在/ usr / bin中创建了一个新的可执行文件,调用了特殊的python36 exe:

string_split()

现在py3运行一个脚本,该脚本专门使用任何参数调用python3安装