问题描述
我已经在Debian 9/Nginx盒子上创建了一个个人PyPI软件包"服务器,以便可以确定性地构建我的服务器.我固定了我所有的Python软件包,并需要确保每当我需要重建电子商务服务器时,我的Python软件包的确切版本及其子依赖项始终可用.
I've created a personal PyPI "packages" server on a Debian 9/Nginx box so that I can make my server builds deterministic. I pin all my Python packages and need to ensure that the exact versions of my Python packages as well as their sub-dependencies are always available whenever I need to rebuild my e-commerce servers.
我使用 pip2pi 程序包在服务器中填充了所需的程序包.但是,当我在客户端服务器上运行"pip install"命令以安装我的软件包时,出现以下错误:
I populated this server with my required packages using the pip2pi package. But when I run the "pip install" command on a client server to install my packages, I'm getting the following error:
Looking in indexes: https://packages.example.com/simple
Collecting Django==1.8.4 (from -r requirements.txt (line 2))
Collecting django-extensions==1.5.7 (from -r requirements.txt (line 3))
Could not find a version that satisfies the requirement django-extensions==1.5.7 (from -r requirements.txt (line 3)) (from versions: )
No matching distribution found for django-extensions==1.5.7 (from -r requirements.txt (line 3))
我的需求文件中大约有40个软件包,所以这仅仅是一个例子. Django软件包将被安装,但django-extensions软件包将使pip失败.
I have about 40 packages in my requirements file so this is just an example of what happens. The Django package will get installed but pip will fail with the django-extensions package.
如果我在任何客户端服务器上运行此命令,则会收到上面显示的错误:
If I run this command on any of my client servers, I get the error shown above:
pip install -r requirements.txt
需求文件如下:
-i https://packages.example.com/simple
Django==1.8.4
django-extensions==1.5.7
(more packages)
现在,在我的软件包服务器上,根软件包目录/var/www/packages具有以下结构:
Now on my package server the root package directory, /var/www/packages, has the following structure:
# /var/www/packages:
├── Django-1.8.4-py2.py3-none-any.whl
├── django_extensions-1.5.7-py2.py3-none-any.whl
├── simple
├── django
│ ├── Django-1.8.4-py2.py3-none-any.whl -> ../../Django-1.8.4-py2.py3-none-any.whl
│ └── index.html
├── django-extensions
│ ├── django-extensions-1.5.7-py2.py3-none-any.whl -> ../../django_extensions-1.5.7-py2.py3-none-any.whl
│ └── index.html
├── index.html
已建立此目录结构,并使用pip2pi的pip2tgz命令安装了软件包:
This directory structure was built and the packages installed using pip2pi's pip2tgz command:
pip2tgz /var/www/packages/ -r requirements.txt
这是pip2tgz读取的需求输入文件:
Here is the requirements input file read by pip2tgz:
-i https://pypi.org/simple
django==1.8.4
django-extensions=1.5.7
(more packages)
这是在软件包服务器上设置nginx根目录的方式:
Here is how the nginx root directory is set on the package server:
server {
...
root /var/www/packages;
...
}
我的软件包服务器上的防火墙设置为允许ping,允许我SSH输入以及所有http和https连接.
The firewall on my package server is set to allow pings, allow me to SSH in, and to all http and https connections.
我在客户端服务器上使用的是Python 3.5.3和pip 19.0.3.
I'm using Python 3.5.3 and pip 19.0.3 on my client servers.
我不确定自己在做什么错. pip命令看起来正确,但是我想知道pip2pi软件包是否正确设置了我的软件包目录.如果我将客户需求文件中的index参数更改为默认值,则 https://pypi.org/simple ,所有软件包都将恢复无误.
I'm not sure what I'm doing wrong. The pip command looks correct but I'm wondering if the pip2pi package is setting up my packages directories correctly. If I change the index argument in my client's requirement file to the default, https://pypi.org/simple, all packages restore without errors.
更新1
如果我尝试从命令行而不是通过需求文件安装django-extensions,我仍然会收到错误消息:
If I try to install django-extensions from the command line instead of via a requirements file, I still get an error:
pip install --index-url=https://packages.example.com/simple/ django-extensions
Looking in indexes: https://packages.example.com/simple/
Collecting django-extensions
Could not find a version that satisfies the requirement django-extensions (from versions: )
No matching distribution found for django-extensions
在检查我的其他软件包时,我确实在这里看到一个模式.每当我尝试安装其中wheel文件名包含下划线(_)但软件包目录的规范化名称中每个Python PEP 503带有连字符(-")的软件包时,都会发生错误.
In examining my other packages, I do see a pattern here. The error occurs whenever I try to install a package in which the wheel file's name contains an underscore ("_") but the package directory's normalized name has a hypen ("-") in it per Python PEP 503.
例如,django-rq失败:
For example, django-rq fails:
directory: simple/django-rq
file: django_rq-0.9.0-py2.py3-none-any.whl
另一方面,django-redis-cache不会失败:
On the other hand, django-redis-cache doesn't fail:
directory: simple/django-redis-cache
file: django-redis-cache-1.6.5.tar.gz
但是另一个区别是,前者是wheel文件,而后者是tgz文件,因此也可以解释该区别.我将继续对此进行调查.
But one other difference is that the former is a wheel file while the latter is a tgz file so that may account for the difference too. I'll continue to investigate this.
更新2
按照Ares的建议,我使用详细选项运行了pip安装:
Per Ares' suggestion, I ran pip install with the verbose option:
pip install --verbose --index-url=https://packages.example.com/simple/ django-rq
这是错误:
Created temporary directory: /tmp/pip-ephem-wheel-cache-g_hx5tb1
Created temporary directory: /tmp/pip-req-tracker-1bt5psaw
Created requirements tracker '/tmp/pip-req-tracker-1bt5psaw'
Created temporary directory: /tmp/pip-install-dqvtv6ek
Looking in indexes: https://packages.example.com/simple/
Collecting django-rq
1 location(s) to search for versions of django-rq:
* https://packages.example.com/simple/django-rq/
Getting page https://packages.example.com/simple/django-rq/
Looking up "https://packages.example.com/simple/django-rq/" in the cache
Request header has "max_age" as 0, cache bypassed
Starting new HTTPS connection (1): packages.example.com:443
https://packages.example.com:443 "GET /simple/django-rq/ HTTP/1.1" 304 0
Analyzing links from page https://packages.example.com/simple/django-rq/
Skipping link https://packages.example.com/simple/django-rq/django-rq-0.9.0-py2.py3-none-any.whl (from https://packages.example.com/simple/django-rq/); wrong project name (not django-rq)
Cleaning up...
Removed build tracker '/tmp/pip-req-tracker-1bt5psaw'
Exception information:
Traceback (most recent call last):
File "/home/flaugher/pip3/venv/lib/python3.5/site-packages/pip/_internal/cli/base_command.py", line 179, in main
status = self.run(options, args)
File "/home/flaugher/pip3/venv/lib/python3.5/site-packages/pip/_internal/commands/install.py", line 315, in run
resolver.resolve(requirement_set)
File "/home/flaugher/pip3/venv/lib/python3.5/site-packages/pip/_internal/resolve.py", line 131, in resolve
self._resolve_one(requirement_set, req)
File "/home/flaugher/pip3/venv/lib/python3.5/site-packages/pip/_internal/resolve.py", line 294, in _resolve_one
abstract_dist = self._get_abstract_dist_for(req_to_install)
File "/home/flaugher/pip3/venv/lib/python3.5/site-packages/pip/_internal/resolve.py", line 242, in _get_abstract_dist_for
self.require_hashes
File "/home/flaugher/pip3/venv/lib/python3.5/site-packages/pip/_internal/operations/prepare.py", line 269, in prepare_linked_requirement
req.populate_link(finder, upgrade_allowed, require_hashes)
File "/home/flaugher/pip3/venv/lib/python3.5/site-packages/pip/_internal/req/req_install.py", line 196, in populate_link
self.link = finder.find_requirement(self, upgrade)
File "/home/flaugher/pip3/venv/lib/python3.5/site-packages/pip/_internal/index.py", line 688, in find_requirement
'No matching distribution found for %s' % req
pip._internal.exceptions.DistributionNotFound: No matching distribution found for django-rq
该键似乎在第15行显示正在跳过链接...错误的项目名称(不是django-rq)".我不确定为什么它会跳过链接.
The key appears to be line 15 where it says "Skipping link... wrong project name (not django-rq)." I'm not sure why it's skipping the link.
推荐答案
它看起来像 pypi服务器一个>将最能满足我的需求.如上所述,它成功安装了pip2pi失败的软件包.它的设置并不复杂,可以通过Nginx或Apache在远程服务器上运行.我发现这篇文章设置PyPI服务器非常有用(尽管确实有一些错字).
It looks like pypi-server will best meet my needs. It succeeds in installing the packages that pip2pi failed on as I described above. It's not overly-complicated to set up and it can be run on a remote server via Nginx or Apache. I found this article Setting up a PyPI server very helpful (although it did have a couple of typos).
这篇关于为什么不从我的个人PyPI服务器安装Python软件包?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!