当前位置: 首页 > news >正文

使用 Docker 搭建私有 PyPI 镜像仓库:支持多平台二进制包同步

docker

在企业内网或离线开发环境中,我们常常需要一个稳定、快速且可控制的 Python 包管理方案。本文将详细介绍如何使用 devpi 和 Docker 构建一个私有的 PyPI 镜像服务器,并实现对 Windows 与 Linux 平台的 64 位二进制包(wheel) 的自动下载、缓存和分发。

通过本教程,你可以:

  • 快速搭建本地 PyPI 缓存服务器;
  • 支持不同操作系统平台(win_amd64 / manylinux);
  • 自动从国内镜像源(阿里云)预下载指定依赖包;
  • 实现高效、安全的企业级 Python 包管理。

🛠️ 准备工作

1. 创建项目结构

首先,在你的项目目录中创建以下文件结构:

pypi-mirror/
├── init/
│   ├── Dockerfile
│   └── setup-devpi.sh
├── docker-compose.yml
├── requirements.txt          # 待安装的包列表
└── devpi-data/               # 数据持久化目录(自动生成)

⚠️ 注意:首次运行前需手动创建空的 devpi-data 目录用于存储 devpi 数据。


2. 编写 Dockerfile(./init/Dockerfile

# 使用 Python 3.10 作为基础镜像(国内加速)
FROM python:3.10# 设置环境变量,使用阿里云 PyPI 镜像
ENV PIP_DEFAULT_TIMEOUT=100 \PIP_RETRIES=5 \PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/ \PIP_TRUSTED_HOST=mirrors.aliyun.com# 安装 devpi 相关组件
RUN pip install --no-cache-dir devpi-server devpi-web devpi-client passlib# 创建数据目录
RUN mkdir -p /data/server# 暴露端口
EXPOSE 3141# 启动 devpi-server
CMD ["devpi-server", "--host", "0.0.0.0", "--port", "3141", "--serverdir", "/data/server"]

📌 说明:

  • 使用阿里云镜像提升国内网络下载速度。
  • 安装了 devpi-server(服务端)、devpi-web(Web 界面)、devpi-client(命令行工具)。
  • 所有数据保存在 /data/server,通过卷挂载实现持久化。

3. 编写初始化脚本(./init/setup-devpi.sh

该脚本负责配置 devpi 用户、索引,并根据 requirements.txt 下载并上传指定包及其依赖。

#!/bin/bash
set -eecho "配置 devpi 客户端..."
devpi use http://localhost:3141# 创建用户
echo "创建用户和索引..."
devpi user -c mirroruser password=securepassword123 || echo "用户已存在"# 登录该用户(关键步骤!否则无法操作索引)
echo "登录新创建的用户..."
devpi login mirroruser --password=securepassword123# 创建主索引
devpi index -c main bases=root/pypi || echo "索引已存在"# 切换到主索引
devpi use mirroruser/main# 创建临时目录
mkdir -p /tmp/packages# 设置 pip 使用阿里云镜像
export PIP_INDEX_URL="https://mirrors.aliyun.com/pypi/simple/"
export PIP_TRUSTED_HOST="mirrors.aliyun.com"echo "开始处理 requirements.txt 中的包..."# 检查 requirements.txt 是否存在
if [ ! -f "/app/requirements.txt" ]; thenecho "错误: /app/requirements.txt 文件不存在!"exit 1
fi# 第一阶段:解析所有包及依赖
all_packages=()
while IFS= read -r package; do[[ -z "$package" || "$package" =~ ^# ]] && continueecho "分析包: $package"# 获取依赖(模拟安装但不实际安装)dependencies=$(pip install --no-deps --dry-run "$package" 2>&1 | grep 'Collecting' | awk '{print $2}' | sed 's/[<=>].*//')all_packages+=("$package")while IFS= read -r dep; do[[ -z "$dep" ]] && continueall_packages+=("$dep")done <<< "$dependencies"
done < /app/requirements.txt# 去重排序
unique_packages=($(printf "%s\n" "${all_packages[@]}" | sort -u))# 第二阶段:下载 64 位平台 wheel 包
echo "正在下载 64 位平台二进制包..."
for package in "${unique_packages[@]}"; doecho "处理 $package..."rm -f /tmp/packages/*  # 清空临时目录# 下载 Windows 64-bit 包(Python 3.13 兼容)echo "  下载 win_amd64 版本..."pip download --only-binary=:all: --python-version 313 --platform win_amd64 \-i https://mirrors.aliyun.com/pypi/simple/ -d /tmp/packages "$package" > /dev/null 2>&1# 下载 Linux x86_64 包(manylinux)echo "  下载 manylinux_2_17_x86_64 版本..."pip download --only-binary=:all: --python-version 313 --platform manylinux_2_17_x86_64 \-i https://mirrors.aliyun.com/pypi/simple/ -d /tmp/packages "$package" > /dev/null 2>&1# 上传到 devpifor whl in /tmp/packages/*.whl; doif [ -f "$whl" ]; thenecho "  上传 $whl 到私有仓库..."devpi upload "$whl"fidone
done# 第三阶段:创建平台专用索引
echo "创建平台过滤索引..."devpi index -c win_amd64 bases=main \mirrorsync=1 \platform=win_amd64 \python_version=3.13 || echo "索引 win_amd64 已存在"devpi index -c linux_x86_64 bases=main \mirrorsync=1 \platform=manylinux_2_17_x86_64 \python_version=3.13 || echo "索引 linux_x86_64 已存在"echo "✅ 初始化完成!DevPI 私有仓库已就绪。"echo ""
echo "📌 使用方式如下:"
echo "   Windows 用户:"
echo "     pip install -i http://<YOUR_LOCAL_IP>:3141/mirroruser/win_amd64/+simple/ <package>"
echo ""
echo "   Linux 用户:"
echo "     pip install -i http://<YOUR_LOCAL_IP>:3141/mirroruser/linux_x86_64/+simple/ <package>"
echo ""
echo "💡 提示:请将 <YOUR_LOCAL_IP> 替换为宿主机 IP 地址(如 192.168.1.100)"

🔐 安全建议:

  • 生产环境下应修改默认密码;
  • 可启用 HTTPS 和认证机制增强安全性。

4. 配置 Docker Compose(docker-compose.yml

version: '3.8'services:devpi:build:context: .dockerfile: init/Dockerfilecontainer_name: pypi-mirrorports:- "3141:3141"volumes:- ./devpi-data:/data/server- ./init/setup-devpi.sh:/setup-devpi.sh- ./requirements.txt:/app/requirements.txtenvironment:- DEVPISERVER_SERVERDIR=/data/serverrestart: unless-stoppedentrypoint: >sh -c "if [ ! -f /data/server/.serverversion ]; thendevpi-init --serverdir /data/server;fi;devpi-server --host 0.0.0.0 --port 3141 --serverdir /data/server &sleep 20 &&/setup-devpi.sh &&wait"

📌 功能说明:

  • 第一次启动时自动初始化 devpi 数据目录;
  • 后续启动直接复用已有数据;
  • 脚本延迟执行确保服务已就绪;
  • 支持容器重启后自动恢复服务。

📥 获取热门包列表并生成 requirements.txt

为了构建一个实用的私有镜像,我们可以基于 PyPI 上最受欢迎的包 来填充初始内容。

步骤一:下载 top-pypi-packages.csv

访问 https://hugovk.github.io/top-pypi-packages/
点击 “Download CSV” 下载最新的 top-pypi-packages.csv 文件。

步骤二:使用 gen_requirements.py 生成 requirements.txt

假设你有一个脚本 gen_requirements.py,其功能是从 CSV 中提取前 N 个最流行包名,输出为 requirements.txt

示例代码(gen_requirements.py):

import csv# 读取 top-pypi-packages.csv,提取前 50 个包
with open('top-pypi-packages.csv', newline='', encoding='utf-8') as f:reader = csv.DictReader(f)packages = [row['project'] for row in reader]# 写入 requirements.txt
with open('requirements.txt', 'w') as f:for pkg in packages[:50]:  # 取前 50 名f.write(f"{pkg}\n")print("✅ 已生成 requirements.txt,包含前 50 个热门 PyPI 包")

运行后生成的 requirements.txt 示例:

requests
urllib3
certifi
idna
charset_normalizer
click
flask
...

▶️ 启动服务

第一步:构建并启动容器

docker-compose up --build

首次运行会经历以下过程:

  1. 构建镜像;
  2. 初始化 devpi 数据目录;
  3. 启动 devpi-server;
  4. 执行 setup-devpi.sh 脚本,下载并上传包;
  5. 创建平台专用索引。

⏳ 时间消耗:取决于 requirements.txt 中包的数量和网络速度,可能需要数分钟。

第二步:查看 Web 界面

打开浏览器访问:

👉 http://localhost:3141/mirroruser/main/+simple/

你将看到所有已上传包的简单索引页面。


💻 客户端安装测试

Windows 用户

pip install -i http://192.168.1.100:3141/mirroruser/win_amd64/+simple/ requests

Linux 用户

pip install -i http://192.168.1.100:3141/mirroruser/linux_x86_64/+simple/ pandas

✅ 成功标志:

  • 不再连接公网 PyPI;
  • 直接从本地服务器下载 .whl 文件;
  • 安装速度快,稳定性高。

🔁 日常使用命令

命令说明
docker-compose up启动服务(无需重建)
docker-compose down停止并移除容器
docker-compose logs查看日志调试问题

✅ 数据已挂载至 ./devpi-data,即使删除容器也不会丢失已缓存的包。


🧩 高级特性与扩展建议

✅ 支持更多平台

可以扩展脚本支持其他平台,例如:

  • macosx_11_0_arm64(M1/M2 Mac)
  • linux_aarch64

只需添加对应的 --platform 参数即可。

✅ 定期更新包

可通过定时任务拉取新版本包,保持私有仓库同步。

✅ 添加身份验证与权限控制

devpi 支持细粒度用户权限管理,可用于团队协作场景。

✅ 集成 CI/CD 流程

在内部 CI 环境中设置此镜像为默认源,避免外部依赖风险。


📌 总结

本文介绍了一种完整的解决方案,利用 devpi + Docker + 阿里云镜像 + 多平台 wheel 分发 技术栈,打造了一个高性能、跨平台、可持久化的私有 PyPI 仓库。

🎯 适用场景:

  • 企业内网隔离环境;
  • 开发团队统一依赖管理;
  • 提升 CI/CD 构建效率;
  • 减少对外部源的依赖与安全风险。

🔧 核心优势:

  • 自动化初始化流程;
  • 支持平台差异化索引;
  • 国内镜像加速下载;
  • 易于部署与维护。

🚀 现在就开始搭建属于你自己的私有 PyPI 仓库吧!

GitHub 参考资源:

  • Devpi 官方文档: https://doc.devpi.net
  • Top PyPI Packages 统计: https://hugovk.github.io/top-pypi-packages/
  • 阿里云 PyPI 镜像: https://mirrors.aliyun.com/pypi/simple/

如有疑问,欢迎留言交流!


文章转载自:

http://zZnJNFYh.trmpj.cn
http://aIBJwOXl.trmpj.cn
http://mFWJdQaw.trmpj.cn
http://tLSjW36k.trmpj.cn
http://zVgRbeJK.trmpj.cn
http://G4j2wFjs.trmpj.cn
http://81CxHKBP.trmpj.cn
http://i8jxgkKt.trmpj.cn
http://KCXicqn5.trmpj.cn
http://kk3iLReY.trmpj.cn
http://f37yNnE1.trmpj.cn
http://5kDxzFv3.trmpj.cn
http://ciIUeDU7.trmpj.cn
http://wrYbSDdZ.trmpj.cn
http://tZsKXLz2.trmpj.cn
http://TpX65dMZ.trmpj.cn
http://xLz7kfxl.trmpj.cn
http://hC5HgQGP.trmpj.cn
http://4qAqYjoy.trmpj.cn
http://MR2uKDEh.trmpj.cn
http://aASFo0g7.trmpj.cn
http://qocrgV90.trmpj.cn
http://Ik9RshvV.trmpj.cn
http://mikwr57F.trmpj.cn
http://thmlrpeI.trmpj.cn
http://HMMPxlBN.trmpj.cn
http://vVTQrtr6.trmpj.cn
http://YMDDg3MI.trmpj.cn
http://A4znnwkY.trmpj.cn
http://xM21gDf2.trmpj.cn
http://www.dtcms.com/a/385005.html

相关文章:

  • HarmonyOS实现快递APP自动识别地址(国际版)
  • IPsec实验笔记
  • 工业IOT平台助力水泥集团实现数字化转型
  • 【CSS】图片自适应等比例缩放
  • Java 21 虚拟线程高并发落地全指南:中间件适配、场景匹配与细节优化的技术实践
  • 设计模式(C++)详解—适配器模式(1)
  • 圆周点生成的数学原理与Python实现
  • 牛客:校门外的树
  • JavaScript数据网格方案AG Grid 34.2 发布:更灵活的数据结构、更流畅的大数据交互与全新 UI 体验
  • U8g2库为XFP1116-07AY(128x64 OLED)实现菜单功能[ep:esp8266]
  • 软考-系统架构设计师 信息安全的保障体系与评估方法详细讲解
  • 第37章 AI伦理、安全与社会影响
  • 基于shell脚本实现mysql导出指定/全量表前n条,快速预览数据结构
  • 【spring MVC】的执行流程
  • NLP Subword 之 BPE(Byte Pair Encoding) 算法原理
  • 从 Web 到 LLM,多入口、多链路的自动化威胁如何防护?
  • Roo Code代码库索引功能
  • 以太网链路聚合实验
  • 机理流程图绘制,如此简单 !
  • 从按钮到接口:权限系统设计的艺术与实践 —— 打造细粒度可扩展的权限架构
  • 3D 打印在道具制作领域的应用调研与轻资产介入策略创意报告
  • Python多进程通信完全指南:打破进程隔离的壁垒
  • webrtc之语音活动下——VAD人声判定原理以及源码详解
  • S32K3平台RTC应用笔记
  • 开源收银系统_大型收银系统源码_OctShop
  • UE5 蓝图接口函数类型知多少?
  • 【MySQL分库分表:海量数据架构的终极解决方案】
  • 深入解析 Apache RocketMQ架构组成与核心组件作用
  • Tomcat下载和安装教程(图文并茂,适合新手)
  • (用Maven)整合SpringBoot,SpringMVC,MyBatis