使用Docker搭建私有PyPI镜像仓库的完整步骤教学
作者:东方佑
在企业内网或离线开发环境中,我们常常需要一个稳定、快速且可控制的 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 -e
echo "配置 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" ]; then
echo "错误: /app/requirements.txt 文件不存在!"
exit 1
fi
# 第一阶段:解析所有包及依赖
all_packages=()
while IFS= read -r package; do
[[ -z "$package" || "$package" =~ ^# ]] && continue
echo "分析包: $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" ]] && continue
all_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[@]}"; do
echo "处理 $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
# 上传到 devpi
for whl in /tmp/packages/*.whl; do
if [ -f "$whl" ]; then
echo " 上传 $whl 到私有仓库..."
devpi upload "$whl"
fi
done
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/Dockerfile
container_name: pypi-mirror
ports:
- "3141:3141"
volumes:
- ./devpi-data:/data/server
- ./init/setup-devpi.sh:/setup-devpi.sh
- ./requirements.txt:/app/requirements.txt
environment:
- DEVPISERVER_SERVERDIR=/data/server
restart: unless-stopped
entrypoint: >
sh -c "
if [ ! -f /data/server/.serverversion ]; then
devpi-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
首次运行会经历以下过程:
- 构建镜像;
- 初始化 devpi 数据目录;
- 启动 devpi-server;
- 执行
setup-devpi.sh脚本,下载并上传包; - 创建平台专用索引。
时间消耗:取决于 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/
到此这篇关于使用Docker搭建私有PyPI镜像仓库的完整步骤教学的文章就介绍到这了,更多相关Docker搭建私有PyPI镜像仓库内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
