如何用 Docker 构建企业级 PyPi 服务?
The following article is from 岛哥的质量效能笔记 Author 岛哥
剧照:怒火·重案
作者:岛哥
来源:岛哥的质量效能笔记
我们平常使用 pip 命令安装 Python 包时,默认是去 https://pypi.python.org/simple/ 源查找相应的包下载并安装的,但是在企业内网环境我们需要发布一些私有包提供给内部用户使用时,就需要搭建自己的 PyPI Server了。
下面是目前已知的一些部署私有仓库服务的方案
框架 | 代理镜像 | 本地缓存 | 搜索 |
devpi | Y | Y | 支持 Web + XML RPC |
DjangoPyPI | Y | N | 支持 Web + XML RPC |
chishop | N | N | 不支持 |
pypiserver | Y | N | 不支持 |
Cheese Shop | N | N | 支持 Web + XML RPC |
localshop | Y | Y | 只支持 XML RPC |
mypypi | N | N | 不支持 |
proxypypi | Y | Y | 不支持 |
Flask-Pypi-Proxy | Y | Y | 不支持 |
devpi有一些特有的功能:
支持本地缓存,可以做到公司内网加速的效果 支持Sphinx文档 提供多索引支持,多索引之间还可以继承,这在维护多版本系统上非常有用 支持集群部署,支持一台或多台服务器部署实现访问加速 支持通过 json 接口,实时监控集群的状态 支持导入导出功能 支持给索引设置 Jenkins 触发器,可以使用 tox 自动测试上传的包 使用插件可以完成Web界面的访问控制,增加私有包的安全
devpi-server 属于核心组件,提供镜像与缓存功能 devpi-web 提供Web界面和查询功能 devpi-lockdown 通过在nginx的帮助下实现对Web界面添加访问控制的功能
FROM suadminwen/python3-ubuntu:latest
WORKDIR /root/
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
RUN apt update \
&& apt install nginx -y
COPY ./nginx-devpi.conf /etc/nginx/sites-enabled/default
COPY ./run.sh /root/
EXPOSE 31415
EXPOSE 80
ENTRYPOINT ["bash", "run.sh"]
server {
server_name 0.0.0.0;
listen 80;
gzip on;
gzip_min_length 2000;
gzip_proxied any;
gzip_types application/json;
proxy_read_timeout 60s;
client_max_body_size 64M;
# set to where your devpi-server state is on the filesystem
root /root/.devpi/server;
# this redirects to the login view when not logged in
recursive_error_pages on;
error_page 401 = @error401;
location @error401 {
return 302 /+login;
}
# lock down everything by default
auth_request /+authcheck;
location = /+login {
auth_request off;
proxy_set_header X-outside-url $scheme://$http_host;
proxy_pass http://localhost:3141;
}
location ~ /\+api$ {
auth_request off;
proxy_set_header X-outside-url $scheme://$http_host;
proxy_pass http://localhost:3141;
}
# try serving static files directly
location ~ /\+f/ {
auth_request off;
# workaround to pass non-GET/HEAD requests through to the named location below
error_page 418 = @proxy_to_app;
if ($request_method !~ (GET)|(HEAD)) {
return 418;
}
expires max;
try_files /+files$uri @proxy_to_app;
}
# try serving docs directly
location ~ /\+doc/ {
auth_request off;
# if the --documentation-path option of devpi-web is used,
# then the root must be set accordingly here
root /root/.devpi/server;
try_files $uri @proxy_to_app;
}
location / {
# workaround to pass all requests to / through to the named location below
error_page 418 = @proxy_to_app;
return 418;
}
location @proxy_to_app {
proxy_pass http://localhost:3141;
proxy_set_header X-outside-url $scheme://$http_host;
proxy_set_header X-Real-IP $remote_addr;
}
location = /+authcheck {
internal;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-outside-url $scheme://$http_host;
proxy_pass http://localhost:3141;
}
}
run.sh
echo -e 'start supervisord'
/usr/local/bin/supervisord -c /root/gen-config/supervisord.conf
echo -e 'start nginx'
nginx -g 'daemon off;'
docker-compose.yml
services:
devpiserver:
container_name: devpiserver
build:
context: .
ports:
- 80:80
- 31415:80
volumes:
- ~/.devpi:/root/.devpi
在准备好上述文件后,先在用户根目录执行下面的命令:
pip install devpi-server
devpi init
然后在docker文件根目录执行下面的命令即可完成服务的启动:
docker-compose up -d
本地的操作是需要使用devpi-client来完成的,执行下面的命令安装依赖:
pip install -U devpi-client
创建连接
devpi use http://devpi.xxxxx.com/
默认的用户是root,密码是空
# 使用root账号登录
devpi login root --password=
# 修改root用户密码为qwe
devpi user -m root password=qwe
# 创建新用户dev并设定密码为qwe
devpi user -c dev password=qwe
# 新用户登录
devpi login dev --password=qwe
# 退出登录
devpi logoff
登录之后才可以进行索引操作
# 创建dev索引
devpi index -c dev bases=root/pypi
# 使用dev索引
devpi use root/dev
# 当仓库中不存在包时,从豆瓣下载包缓存到本地(默认是从官方源 https://pypi.python.org/simple/ 下载)
devpi index root/dev mirror_url = “https://pypi.doubanio.com/simple/"
# devpi push 命令是将包从一个索引推送到另外一个索引,例如将包example推送到root/dev
devpi push example==1.0 root/dev
--with-docs 参数,连带docs文件一块上传,支持 sphinx 创建的文档 --formats bdist_wheel 参数,上传wheel格式的包,需要安装wheel库, pip install wheel
devpi use http://pypi-xx.com/
devpi login root --password=qwe
devpi use root/dev
devpi upload --formats bdist_wheel
devpi upload --with-docs
devpi upload
删除私有包
devpi remove example
devpi remove example>=1.0.1
无访问限制:
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]
无访问限制:
[global]
timeout = 60
index-url = http://pypi-xx.com/root/dev/+simple/
[install]
trusted-host = pypi-xx.com
有访问限制:
[global]
timeout = 60
index-url = http://[user]:[password]@[host]/root/dev/+simple/
[install]
trusted-host = pypi-xx.com
如果想要前移服务器的文件,首先需要找到devpi服务器数据所在地址,进入server目录中找到 '+ files' 目录拷贝出来,然后使用下面命令把已有的私有包导入新的服务中:
devpi upload --from-dir '+files'
还不过瘾?试试它们