【问题标题】:python install without pip on ubuntu在ubuntu上没有pip的python安装
【发布时间】:2019-04-07 03:18:04
【问题描述】:

我需要在一个自定义 Docker 容器中安装一个 Python 包,该容器是我从官方“ubuntu”Docker 镜像构建的,所以我想尽量减少它使用的空间。 Python3 可以正常安装并运行,但由于某种原因,不包括 pip。

所以我是通过apt install python3-pip 安装的,它可以工作,但它的容量高达 300 兆,并且需要几分钟才能安装(显然是因为它安装了大量的东西来从 gcc 等构建二进制包)。

当然,我可以在安装我想要的依赖项后从映像中卸载 python3-pip,另外使用apt autoremove 来摆脱 299 兆。然而,这需要一分钟。

因此,尽管上述方法有效,但它显着增加了我的 Docker 映像的构建时间。所以我试着看看是否有一种方法可以在没有 pip 的情况下安装依赖项:

我尝试从 PyPI 下载依赖项的 .tar.gz,提取并尝试了 python3 setup.py install,但这给我带来了一个奇怪的错误:

Traceback (most recent call last):
  File "setup.py", line 59, in <module>
    from distutils import log
ImportError: cannot import name 'log'

我想也许我需要安装 setuptools,或者升级 distutils。

我尝试使用官方网站上的get-pip.py,但也失败了:

Traceback (most recent call last):
  File "get-pip.py", line 20890, in <module>
    main()
  File "get-pip.py", line 197, in main
    bootstrap(tmpdir=tmpdir)
  File "get-pip.py", line 82, in bootstrap
    import pip._internal
  File "/tmp/tmpjpa5gs_x/pip.zip/pip/_internal/__init__.py", line 40, in <module>
  File "/tmp/tmpjpa5gs_x/pip.zip/pip/_internal/cli/autocompletion.py", line 8, in <module>
  File "/tmp/tmpjpa5gs_x/pip.zip/pip/_internal/cli/main_parser.py", line 8, in <module>
  File "/tmp/tmpjpa5gs_x/pip.zip/pip/_internal/cli/cmdoptions.py", line 17, in <module>
  File "/tmp/tmpjpa5gs_x/pip.zip/pip/_internal/locations.py", line 10, in <module>
ImportError: cannot import name 'sysconfig'

这很奇怪,因为如果我启动 python3,import sysconfig 工作正常。

我还尝试了apt install python-pyyaml(我在 Docker 映像中需要的依赖项),但这似乎不存在。

所以我别无选择。

【问题讨论】:

  • pip 实际上确实需要所有这些(C 编译器和其他构建工具),因为 pip 包可能包含 C 代码或与二进制包链接。
  • 是的,我知道为什么这些对于涵盖所有可能的构建/安装案例是必要的,对于一两个不需要 C (AFAIK) 的库来说似乎有点过分了。应该有一个用于纯 Python 包的“轻量级”版本的 pip,它的大小可能是 1/100。

标签: python-3.x docker ubuntu pip


【解决方案1】:

我遇到了类似的问题,想提供一个替代解决方案。

在 Ubuntu 20.04 build-essential 和 python3-dev 是 python3-pip 的推荐软件包,因此您可以使用 --no-install-recommends 选项跳过它们:

RUN apt update -y && \
    apt install python3 python3-pip --no-install-recommends -y && \
    apt clean

这使我的图像从 420MB 变为 165MB,显然构建时间也更快了。

注意:这适用于纯 Python 包,但如果你想编译任何东西,你可能需要 build-essential 和 python3-dev

有用的链接

【讨论】:

    【解决方案2】:

    用于 PyYAML 的 Debian 和 Ubuntu 软件包称为 python-yaml,而不是 python-pyyaml

    sudo apt install python-yaml
    

    sudo apt install python3-yaml
    

    分别。

    (在 Debian/Ubuntu 软件包名称中,删除 Python 软件包可能具有的任何额外的“py”前缀似乎很常见:它也是 apt install python-tz 而不是 python-pytz。他们似乎不喜欢py-冗余。)

    【讨论】:

    • +1 是一种完全不需要安装 pip 的方法,我不知道!但我的问题仍然存在:如果你有一个纯 Python 包,有没有办法在没有完整 pip 的情况下安装,比如 setuptools 或其他东西,我希望我的问题中的错误能提示我做错了什么。
    • 我添加了该地址的答案,该地址解决了 python-something apt install 不存在的情况
    • 在 Ubuntu 18.04 中,这并没有为我提供 Python 模块。自 2018 年以来,包名称是否已更改?
    【解决方案3】:

    几年来,我一直在 Docker (Ubuntu) 容器中从 pip-get.py 安装 pip 没有问题。对我来说,这是避免 pip-out-of-date 警告或(在某个时间点前一段时间)与 SSL 相关的错误的最佳方法。

    所以你的答案的第二部分很接近,但是你的 python 安装似乎有点太小了,你需要python-distutils 提供的sysconfig。你可以试试这个相当简单的Dockerfile

    FROM ubuntu:latest
    
    MAINTAINER Anthon
    
    ENV DEBIAN_FRONTEND noninteractive
    
    RUN apt-get update && apt-get install -y \
      python3 \
      python3-distutils \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*
    
    # this gets you the latest pip
    COPY pip/get-pip.py /tmp/get-pip.py
    RUN python3 /tmp/get-pip.py
    
    RUN pip3 install pyyaml
    

    我使用这个 Makefile:

    doit:   pip/get-pip.py
            docker build .
    
    pip/get-pip.py:
            -@mkdir pip
            curl https://bootstrap.pypa.io/get-pip.py -o pip/get-pip.py
    

    (那些需要在缩进的行上是 TAB 字符)以确保 pip-get.py 可从上下文中获得(您当然可以从 Dockerfile 中下载它,但这不是必需的)。以成功的 PyYAML 安装结束,但它会很慢。

    我建议您开始使用 ruamel.yaml(免责声明:我是该软件包的作者),将 Dockerfile 的最后一行更改为:

    RUN pip3 install ruamel.yaml
    

    除了它所基于的原始 PyYAML 代码中的许多错误修复之外,ruamel.yaml 支持 YAML 1.2 YAML 1.1(在 2009 年被替换并且 PyYAML 支持的版本),并从.whl 文件,因此您的容器中将拥有快速的 C 加载器(PyYAML 不会这样做)。

    您可以使用 ruamel.yaml 中的 C-loader 加载 YAML 文件:

    from pathlib import Path
    from ruamel.yaml import YAML
    
    
    path = Path('yourfile.yaml')
    yaml = YAML(typ='safe')
    data = yaml.load(path)
    

    【讨论】:

    • 你问题的第一个错误也是python-distutils没有安装在你的容器中造成的。
    【解决方案4】:

    当没有可用于 python 包的apt install something 时,这里是如何做到的。感谢@Anthon 和@digitalarbeiter,因为他们的回答提供了重要的信息,可以帮助您找到解决方案。

    • 通过 setup.py 文件安装(尤其适用于 Ubuntu Docker 容器):

      • 对我来说足够了

        apt install python3-distutils
        <download package, tar xvf, cd to folder>
        python3 setup.py install
        
      • 这种安装方法仅适用于纯 Python 包(应该不足为奇),这意味着具有非纯 Python 依赖项的 Python 包可能无法安装,或者,如果安装,将具有某些功能不可用。

      • 请注意,即使 安装 python3-distutils,python3 -m distutils 也有效;这意味着 Python3 通过apt install python3 附带的内置 distutils 不是完整的 distutils;我不知道,这个事实有没有在任何地方提到过?
    • 在没有 gcc 工具链的情况下安装 pip:对我来说足够了

      apt install python3-distutils
      wget https://bootstrap.pypa.io/get-pip.py
      python3 get-pip.py
      

      然后pip install pyyaml 完成。它似乎是从.tar.gz 安装的,所以它也是纯 Python 实现。不奇怪。如果无法通过 apt install python3-&lt;package&gt; 安装包,则此技术很有用

    上述方法只需要几兆的磁盘空间。

    对我来说,还有一些缺失的部分是:

    • apt install python3-&lt;something&gt;

      • 我错过了许多 Python 包在 Debian 中以这种方式分发的事实,这对于具有 C 实现(或 C 依赖项)的包来说很方便,因为不需要编译。
      • 而且我不知道对于在 PyPI 上称为 py&lt;something&gt; 的软件包,apt install 是 python3-&lt;something&gt; 而不是 python3-py&lt;something&gt;。不幸的是 apt search pyyaml 在这里没有帮助。
    • apt search &lt;something&gt;:我有点忘记了它,因为(桌面)Ubuntu 上的 bash 会在找不到命令时自动建议要下载的正确包。

      • 特别是apt search yaml 产生了 81 个包,这些包提供了多种语言(Python 2、Python 3、nodejs、Java、Go、Ruby、Erlang、Lua、Perl、C、C++、Clojure)的 YAML 读/写,linter,架构验证器等。
      • 多个搜索词被 AND 运算,所以 apt search yaml python3 显示了我错过的 python3-yaml。
      • 很遗憾,apt search pyyaml 没有产生任何结果,尽管apt show python3-yamlSourceHomepage 字段包含单词“pyyaml”。我找不到让search 包含这些字段的方法。

    【讨论】:

      猜你喜欢
      • 2022-11-15
      • 1970-01-01
      • 1970-01-01
      • 2016-02-16
      • 1970-01-01
      • 2021-12-20
      • 2019-07-01
      • 2023-03-18
      相关资源
      最近更新 更多