一、介绍
利用 pypi-server 搭建私有的 pypi 仓库
二、搭建
1. 拉取镜像
docker pull pypiserver/pypiserver2. 创建一个用来保存私有库包文件的文件夹
mkdir /root/pypi && mkdir /root/pypi/packages3. 创建不带密码和用户验证的 pypi 私有仓库
docker run --name 'pypi' --restart always -v /root/pypi/packages:/data/packages -p 8080:8080 -d pypiserver/pypiserver -P . -a . packages4. 创建带密码和用户验证的 pypi 私有仓库
创建
.htpasswd文件,格式为“用户名:密码”
Window:通过文本文档创建,另存为".htpasswd"(带双引号)
Linux:用htpasswd -sc .htpasswd <username>来创建创建容器
docker run --name 'pypi' --restart always -v /root/pypi/packages:/data/packages -v /root/pypi/.htpasswd:/data/.htpasswd -p 8080:8080 -d pypiserver/pypiserver -P .htpasswd packages设置权限
docker exec -it pypi bash cd /data chmod 777 -R packages
三、上传
1. 编辑 .pypirc 文件
Linux 位于:
~/.pypircWindows 位于:
%USERNAME%/.pypirc)
[distutils]
index-servers =
pypi
pypitest
[pypi] # 官方PYPI源信息
repository: https://pypi.python.org/pypi
username:
password:
[pypitest] # 自己搭建的PYPI源信息
repository: http://127.0.0.1:8080/
username:
password:2. 上传
twine upload -r test-pypi dist/* (如果有账号密码,按提示输入即可)
twine upload --repository-url http://127.0.01:8080 dist/* (不设置.pypirc的情况下)四、拉取
pip install [package-name] -i http://127.0.0.1:8080 --trusted-host 127.0.0.1也可以通过设置配置文件省去每次输入源地址的麻烦
Linux:
~/.pip/pip.confWindows:
%APPDATA%/pip/pip.ini[global] timeout = 10 index-url=http://service.xxx.com:8081/simple extra-index-url=https://pypi.douban.com/simple [install] trusted-host = service.xxx.com
五、补充
1. docker-compose 结合 nginx 配置
pypi.yaml
version: "3.5"
services:
pypi:
image: pypiserver/pypiserver
container_name: pypi
restart: always
networks:
- nginx
volumes:
- /home/pypi/packages:/data/packages
- /home/pypi/.htpasswd:/data/.htpasswd
environment:
- TZ=Asia/Shanghai
ports:
- "8081:8080"
command: -P /data/.htpasswd /data/packages --fallback-url https://pypi.tuna.tsinghua.edu.cn/simple
networks:
nginx:
external: truenginx.conf
client_max_body_size 4096m;
client_body_buffer_size 30M;
server {
listen 80;
server_name pypi.xxxx.com;
location / {
proxy_pass http://pypi:8080; # 因为 pypi 加入了 nginx 的网络,这里要写容器内的端口8080(本机访问通过 localhost:8081)
}
}.pypirc
[distutils]
index-servers =
pypi-private
[pypi-private]
repository: http://pypi.xxxx.com
username:test
password:test2. pip 的拉包逻辑
从 index-url 和 extra-index-url 查找,拉取「版本号最高」的包(并不具有真正意义上的优先级,从源码的角度来讲可能是首先检查第一个,但是不应该依赖这个来区分优先度,具体的介绍可以看「这篇文章」
3. pypi-server 的推包逻辑(以 demo 为例)
推送本地仓库(
pypi-server)中的 demo 包若本地仓库当中没有找到
demo包,则去pypi.org中查找
基于这个流程,会导致假如我在pip.ini中同时设置了多个源地址(公有源地址和私有源地址),我在私有源上传了一个公有源同名的包,例:`request-0.01.whl`, 我使用pip install request的时候会导致我拉不到私有源中的requests包(版本号低于公有源中的requests包版本号)注:只要在
pip.ini设置了一个公有源地址pip install requests -i http://localhost:8080/simple --trusted-host localhostpip install requests --extra-index-url http://localhost:8080/simple --trusted-host localhostpip install -r requirements.txt -i http://localhost:8080/simple --trusted-host localhost上述三种方式都是拉取不到 requests-0.01.whl 包的
4. 解决私有包和公有包冲突:
私有库中的包名 以
$ORG_NAME开头检查
pypi.org的中的包名,选择上面不存在的包名作为包名pip.ini不设置任何公有源地址,公有源的包放在requirements.txt,私有源的包放在private-requirements.txt,拉取的时候使用pip3 install -i https://pypi.douban.com/simple -r requirements.txt和pip3 install -r private-requirements.txt --trusted-host localhost -i http://localhost:8080/simple关于这方面的讨论:「How are people avoiding name conflicts?」
Dockerfile 配置
FROM python:3 ADD . /code WORKDIR /code RUN pip3 install -r requirements.txt -i https://pypi.douban.com/simple RUN pip3 install -r private-requirements.txt --trusted-host localhost -i http://localhost:8080/simple RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime CMD python -u main.py
pip.ini只设置私有源地址,在搭建pypi的时候,设置--fallback-url [url]url 填写公有源地址(可以填写国内源来加速)所有包都通过私有源拉取,私有源不存在的包它会自动去公有源追溯。其他关于
pypi-server配置选项--disable-fallback禁止在找不到包的时候跳转到pypi官网链接--fallback-url [url]指明找不到包需要跳转的链接
评论