【pypi镜像源】使用devpi实现python镜像源代理(缓存加速,私有仓库,版本控制)
【pypi镜像源】使用devpi实现python镜像源代理(缓存加速,私有仓库,版本控制)
文章目录
- 1、背景与目标
- 2、devpi-server 服务端搭建
- 3、devpi 镜像源使用
1、背景与目标
背景1(访问速度优化):
- 直接用pip安装包会访问官方源,在国内速度很慢,通常用pip的清华/阿里云源替代。
- 但即便如此,这些远程pypi源网速也不稳定,而且比如pytorch/tensorflow这种几百兆的大型包,下载仍然费时,如果给新人配环境,还要重复下载。
- 这就需要一个缓存pypi服务器来做中转,在内网中下载缓存包,相当于直接拷贝,配环境速度起飞。
- 期望:
缓存机制:内置缓存机制,提升包下载速度,节省带宽(优化访问速度)。
简易配置:通过简单的配置即可快速部署和使用,降低维护成本(考虑docker部署)。
灵活部署:支持多种部署方式,可单机使用,也支持多服务器分布式部署(支持挂载公共对象存储、文件存储)。
背景2(私有镜像包):
- 私有仓库:期望仅用于内网,局域网的软件包。
- 版本控制:更近于一步的,用户期望创建和管理私人PyPI服务器上的索引,实现包的版本控制。
- 权限控制:提供用户和权限管理,确保包的安全性。
技术选型:
- 常见的缓存代理方案:devpi 缓存代理, Nexus 缓存代理, JFrog Artifactory 缓存代理
- 维度
类型
核心功能
部署复杂度
存储需求
维护成本
私有包支持
权限控制
高可用性
适用场景
优点
缺点 - Nexus:维护成本较高,虽然支持py以外的源但是目前用不上
- JFrog Artifactory:需要商业授权,并且维护成本较高,仅支持集群部署
- devpi:因此devpi是目前最合适的方案
- pypi-server :官方推荐的一个服务器,但主要用做上传私有包。上传方便,直接拷贝安装包到文件夹即可。但目前没查到缓存已下载包的方法,使用时和其他源是并列关系。
- bendersnatch : 功能也很强大,但会把源镜像的包全部同步到本地,需要大量存储空间。
参考资料:1,2, 3,5,6
2、devpi-server 服务端搭建
github, 官方文档
devpi的组成:
- 需要python>=3.7
- 使用版本 devpi2.2.0, devpi-client5.2.3, devpi-server==6.4.0
- 虽然包名叫devpi,但在当前版本(devpi-server==6.4.0),功能已经被分为客户端 devpi-client 和服务端 devpi-server
- devpi-client: 直接使用devpi的命令调用的,专门管理已经启动的服务(index,user等指令)
- devpi-server: 加参数用来启动服务器的。只有先启动devpi服务,client才能控制(use指令)
- devpi-web: 一个网页版客户端,和cli版本的功能互相补全(或者说两个客户端功能都残废)。
网页地址和 index_url 相同。网页上可以搜索包名,点击对应版本的安装包可以直接下载。如果已经缓存过,描述中会显示文件大小,反之说明没有本地缓存。 - devpi-init: 最新版本下(devpi-server 6.14.0),使用配置文件初始化devpi的方式。
- devpi配置:目前还没有找到一步到位配置devpi的方法。
首次启动服务器时,mirror_url不能通过config文件传递给程序,只能用上文方式登陆后再修改。但还好,只需要配置一次。这些配置文件会存放在server目录中的数据库文件。
devpi-server 服务搭建
# 虚拟环境
python3 -m venv devpi
source devpi/bin/activate# 安装
pip install devpi-server
devpi-server --version # devpi-server 6.14.0
devpi --version # devpi-client 7.2.0# 初始化
# devpi的配置和缓存安装包的文件夹。不指定目录默认为~/.devpi/server
# devpi-init --serverdir=[PATH]
rm -rf ~/.devpi/server
devpi-init --configfile devpi-server.yml
devpi-server --configfile devpi-server.yml# 启动服务
# http://localhost:3141/
devpi-server --host=[HOST] --port=[PORT] --serverdir=[PATH]
devpi-server
手动配置索引
# 切换到指定索引
devpi use http://localhost:3141
lsof -i :3141# 用户管理
devpi user -l # 查看用户列表
devpi login root --password '' # 默认用户为root 密码为空
devpi user -m root password=123 # 修改密码为123
devpi user -c user1 password=123 # 创建新用户
devpi login user1 --password=123
devpi logout# 索引管理
# 第一次启动后,会自动从python官方源下载索引
# 每个用户可以创建多个index,index直接还可以继承,默认为root/pypi
devpi upload --index user1/thu # 上传包
devpi index -c user1/thu bases=root/pypi # 创建索引
devpi use user1/thu # 使用索引
devpi index root/pypi # 查看索引配置
# http://localhost:3141/root/pypi:
# type=mirror
# volatile=False
# mirror_url=https://mirrors.aliyun.com/pypi/simple/
# mirror_web_url_fmt=https://mirrors.aliyun.com/pypi/simple/{name}/
# title=PyPI
索引镜像源切换
# 切换镜像源地址=>阿里云
# 同步完成后,会删除旧索引,索引都在indices文件夹中
# 网页地址:http://localhost:3141/root/pypi ,或者看 devpi-server 的日志
devpi login root --password ''
devpi index root/pypi "mirror_web_url_fmt=https://mirrors.aliyun.com/pypi/simple/{name}/" "mirror_url=https://mirrors.aliyun.com/pypi/simple/"
devpi index root/pypi "mirror_web_url_fmt=https://pypi.tuna.tsinghua.edu.cn/simple/{name}/" "mirror_url=https://pypi.tuna.tsinghua.edu.cn/simple/"# 尝试切换多个源
devpi index --delete root/thu
devpi index -c root/thu
devpi index root/thu "mirror_web_url_fmt=https://pypi.tuna.tsinghua.edu.cn/simple/{name}/" "mirror_url=https://pypi.tuna.tsinghua.edu.cn/simple/"
上传私有包
- devpi 的 index有两种类型,mirror 和 stage,前者就是默认使用的,拉取远程镜像,但不能传文件到这个 index中。
- 这时需要创建新的 index,指定 stage 类型。然后 devpi use 这个 index,再 devpi upload 本地包。(更多的操作例如本地发布包,也有对应的指令)
- 当我下载时,devpi 会先搜索上传的包,如果没有找到依然能通过 mirror 的 index 来下载,则可以修改 bases,指向 root/pypi,这样就串联起来了。
可能的dockerfile
# 使用官方的带有Python的Ubuntu镜像
FROM python:3.9-slim# 设置工作目录
WORKDIR /root/# 安装 supervisor 和 devpi 相关包
RUN pip install supervisor
RUN mkdir /devpi
RUN pip install devpi-server devpi-web devpi-lockdown \&& devpi-init \&& devpi-gen-config --host 0.0.0.0 --port 3141# 安装 Nginx
RUN apt-get update \&& apt-get install -y nginx# 复制 Nginx 配置文件和启动脚本
COPY ./nginx-devpi.conf /etc/nginx/sites-enabled/default
COPY ./run.sh /root/# 暴露 devpi 和 Nginx 的端口
EXPOSE 3141
EXPOSE 80# 设置启动脚本
ENTRYPOINT ["bash", "run.sh"]
参考资料:1 , 2
3、devpi 镜像源使用
pip config 配置,和使用阿里云/清华源一样
1、临时使用
在pip install后添加 index_url 和 trusted_host
# 语法
pip install requests -i 镜像URL --trusted-host 信任的域名
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn# 可选源
清华:https://pypi.tuna.tsinghua.edu.cn/simple
阿里云:https://mirrors.aliyun.com/pypi/simple/
豆瓣:https://pypi.doubanio.com/simple/# devpi
pip install -i "http://[host]/root/dev/+simple/" [package] --trusted-host [host]
pip install -i "http://[user]:[password]@[host]/root/dev/+simple/" [package] --trusted-host [host]# 例子
pip install -i http://localhost:3141/root/pypi ansible
pip install -i http://user1:123@localhost:3141/user1/thu ansible
2、长期使用
修改本地 pip.conf 文件,默认在~/.pip/pip.conf。
[global]
trusted-host=[HOST]
index-url=http://[HOST]:[PORT]/root/pypi/
# extra-index-url=http://mirrors.aliyun.com/pypi/simple/
timeout=120