使用Docker搭建私有PyPI鏡像倉(cāng)庫(kù)的完整步驟教學(xué)
在企業(yè)內(nèi)網(wǎng)或離線(xiàn)開(kāi)發(fā)環(huán)境中,我們常常需要一個(gè)穩(wěn)定、快速且可控制的 Python 包管理方案。本文將詳細(xì)介紹如何使用 devpi 和 Docker 構(gòu)建一個(gè)私有的 PyPI 鏡像服務(wù)器,并實(shí)現(xiàn)對(duì) Windows 與 Linux 平臺(tái)的 64 位二進(jìn)制包(wheel) 的自動(dòng)下載、緩存和分發(fā)。
通過(guò)本教程,你可以:
- 快速搭建本地 PyPI 緩存服務(wù)器;
- 支持不同操作系統(tǒng)平臺(tái)(win_amd64 / manylinux);
- 自動(dòng)從國(guó)內(nèi)鏡像源(阿里云)預(yù)下載指定依賴(lài)包;
- 實(shí)現(xiàn)高效、安全的企業(yè)級(jí) Python 包管理。
準(zhǔn)備工作
1. 創(chuàng)建項(xiàng)目結(jié)構(gòu)
首先,在你的項(xiàng)目目錄中創(chuàng)建以下文件結(jié)構(gòu):
pypi-mirror/
├── init/
│ ├── Dockerfile
│ └── setup-devpi.sh
├── docker-compose.yml
├── requirements.txt # 待安裝的包列表
└── devpi-data/ # 數(shù)據(jù)持久化目錄(自動(dòng)生成)
注意:首次運(yùn)行前需手動(dòng)創(chuàng)建空的 devpi-data 目錄用于存儲(chǔ) devpi 數(shù)據(jù)。
2. 編寫(xiě) Dockerfile(./init/Dockerfile)
# 使用 Python 3.10 作為基礎(chǔ)鏡像(國(guó)內(nèi)加速)
FROM python:3.10
# 設(shè)置環(huán)境變量,使用阿里云 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 相關(guān)組件
RUN pip install --no-cache-dir devpi-server devpi-web devpi-client passlib
# 創(chuàng)建數(shù)據(jù)目錄
RUN mkdir -p /data/server
# 暴露端口
EXPOSE 3141
# 啟動(dòng) devpi-server
CMD ["devpi-server", "--host", "0.0.0.0", "--port", "3141", "--serverdir", "/data/server"]
說(shuō)明:
- 使用阿里云鏡像提升國(guó)內(nèi)網(wǎng)絡(luò)下載速度。
- 安裝了
devpi-server(服務(wù)端)、devpi-web(Web 界面)、devpi-client(命令行工具)。 - 所有數(shù)據(jù)保存在
/data/server,通過(guò)卷掛載實(shí)現(xiàn)持久化。
3. 編寫(xiě)初始化腳本(./init/setup-devpi.sh)
該腳本負(fù)責(zé)配置 devpi 用戶(hù)、索引,并根據(jù) requirements.txt 下載并上傳指定包及其依賴(lài)。
#!/bin/bash
set -e
echo "配置 devpi 客戶(hù)端..."
devpi use http://localhost:3141
# 創(chuàng)建用戶(hù)
echo "創(chuàng)建用戶(hù)和索引..."
devpi user -c mirroruser password=securepassword123 || echo "用戶(hù)已存在"
# 登錄該用戶(hù)(關(guān)鍵步驟!否則無(wú)法操作索引)
echo "登錄新創(chuàng)建的用戶(hù)..."
devpi login mirroruser --password=securepassword123
# 創(chuàng)建主索引
devpi index -c main bases=root/pypi || echo "索引已存在"
# 切換到主索引
devpi use mirroruser/main
# 創(chuàng)建臨時(shí)目錄
mkdir -p /tmp/packages
# 設(shè)置 pip 使用阿里云鏡像
export PIP_INDEX_URL="https://mirrors.aliyun.com/pypi/simple/"
export PIP_TRUSTED_HOST="mirrors.aliyun.com"
echo "開(kāi)始處理 requirements.txt 中的包..."
# 檢查 requirements.txt 是否存在
if [ ! -f "/app/requirements.txt" ]; then
echo "錯(cuò)誤: /app/requirements.txt 文件不存在!"
exit 1
fi
# 第一階段:解析所有包及依賴(lài)
all_packages=()
while IFS= read -r package; do
[[ -z "$package" || "$package" =~ ^# ]] && continue
echo "分析包: $package"
# 獲取依賴(lài)(模擬安裝但不實(shí)際安裝)
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 位平臺(tái) wheel 包
echo "正在下載 64 位平臺(tái)二進(jìn)制包..."
for package in "${unique_packages[@]}"; do
echo "處理 $package..."
rm -f /tmp/packages/* # 清空臨時(shí)目錄
# 下載 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 到私有倉(cāng)庫(kù)..."
devpi upload "$whl"
fi
done
done
# 第三階段:創(chuàng)建平臺(tái)專(zhuān)用索引
echo "創(chuàng)建平臺(tái)過(guò)濾索引..."
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 私有倉(cāng)庫(kù)已就緒。"
echo ""
echo "?? 使用方式如下:"
echo " Windows 用戶(hù):"
echo " pip install -i http://<YOUR_LOCAL_IP>:3141/mirroruser/win_amd64/+simple/ <package>"
echo ""
echo " Linux 用戶(hù):"
echo " pip install -i http://<YOUR_LOCAL_IP>:3141/mirroruser/linux_x86_64/+simple/ <package>"
echo ""
echo "?? 提示:請(qǐng)將 <YOUR_LOCAL_IP> 替換為宿主機(jī) IP 地址(如 192.168.1.100)"
安全建議:
- 生產(chǎn)環(huán)境下應(yīng)修改默認(rèn)密碼;
- 可啟用 HTTPS 和認(rèn)證機(jī)制增強(qiáng)安全性。
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
"
功能說(shuō)明:
- 第一次啟動(dòng)時(shí)自動(dòng)初始化 devpi 數(shù)據(jù)目錄;
- 后續(xù)啟動(dòng)直接復(fù)用已有數(shù)據(jù);
- 腳本延遲執(zhí)行確保服務(wù)已就緒;
- 支持容器重啟后自動(dòng)恢復(fù)服務(wù)。
獲取熱門(mén)包列表并生成 requirements.txt
為了構(gòu)建一個(gè)實(shí)用的私有鏡像,我們可以基于 PyPI 上最受歡迎的包 來(lái)填充初始內(nèi)容。
步驟一:下載 top-pypi-packages.csv
訪(fǎng)問(wèn) https://hugovk.github.io/top-pypi-packages/
點(diǎn)擊 “Download CSV” 下載最新的 top-pypi-packages.csv 文件。
步驟二:使用 gen_requirements.py 生成 requirements.txt
假設(shè)你有一個(gè)腳本 gen_requirements.py,其功能是從 CSV 中提取前 N 個(gè)最流行包名,輸出為 requirements.txt。
示例代碼(gen_requirements.py):
import csv
# 讀取 top-pypi-packages.csv,提取前 50 個(gè)包
with open('top-pypi-packages.csv', newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
packages = [row['project'] for row in reader]
# 寫(xiě)入 requirements.txt
with open('requirements.txt', 'w') as f:
for pkg in packages[:50]: # 取前 50 名
f.write(f"{pkg}\n")
print("? 已生成 requirements.txt,包含前 50 個(gè)熱門(mén) PyPI 包")
運(yùn)行后生成的 requirements.txt 示例:
requests urllib3 certifi idna charset_normalizer click flask ...
啟動(dòng)服務(wù)
第一步:構(gòu)建并啟動(dòng)容器
docker-compose up --build
首次運(yùn)行會(huì)經(jīng)歷以下過(guò)程:
- 構(gòu)建鏡像;
- 初始化 devpi 數(shù)據(jù)目錄;
- 啟動(dòng) devpi-server;
- 執(zhí)行
setup-devpi.sh腳本,下載并上傳包; - 創(chuàng)建平臺(tái)專(zhuān)用索引。
時(shí)間消耗:取決于 requirements.txt 中包的數(shù)量和網(wǎng)絡(luò)速度,可能需要數(shù)分鐘。
第二步:查看 Web 界面
打開(kāi)瀏覽器訪(fǎng)問(wèn):
http://localhost:3141/mirroruser/main/+simple/
你將看到所有已上傳包的簡(jiǎn)單索引頁(yè)面。
客戶(hù)端安裝測(cè)試
Windows 用戶(hù)
pip install -i http://192.168.1.100:3141/mirroruser/win_amd64/+simple/ requests
Linux 用戶(hù)
pip install -i http://192.168.1.100:3141/mirroruser/linux_x86_64/+simple/ pandas
成功標(biāo)志:
- 不再連接公網(wǎng) PyPI;
- 直接從本地服務(wù)器下載
.whl文件; - 安裝速度快,穩(wěn)定性高。
日常使用命令
| 命令 | 說(shuō)明 |
|---|---|
| docker-compose up | 啟動(dòng)服務(wù)(無(wú)需重建) |
| docker-compose down | 停止并移除容器 |
| docker-compose logs | 查看日志調(diào)試問(wèn)題 |
數(shù)據(jù)已掛載至 ./devpi-data,即使刪除容器也不會(huì)丟失已緩存的包。
高級(jí)特性與擴(kuò)展建議
支持更多平臺(tái)
可以擴(kuò)展腳本支持其他平臺(tái),例如:
macosx_11_0_arm64(M1/M2 Mac)linux_aarch64
只需添加對(duì)應(yīng)的 --platform 參數(shù)即可。
定期更新包
可通過(guò)定時(shí)任務(wù)拉取新版本包,保持私有倉(cāng)庫(kù)同步。
添加身份驗(yàn)證與權(quán)限控制
devpi 支持細(xì)粒度用戶(hù)權(quán)限管理,可用于團(tuán)隊(duì)協(xié)作場(chǎng)景。
集成 CI/CD 流程
在內(nèi)部 CI 環(huán)境中設(shè)置此鏡像為默認(rèn)源,避免外部依賴(lài)風(fēng)險(xiǎn)。
總結(jié)
本文介紹了一種完整的解決方案,利用 devpi + Docker + 阿里云鏡像 + 多平臺(tái) wheel 分發(fā) 技術(shù)棧,打造了一個(gè)高性能、跨平臺(tái)、可持久化的私有 PyPI 倉(cāng)庫(kù)。
適用場(chǎng)景:
- 企業(yè)內(nèi)網(wǎng)隔離環(huán)境;
- 開(kāi)發(fā)團(tuán)隊(duì)統(tǒng)一依賴(lài)管理;
- 提升 CI/CD 構(gòu)建效率;
- 減少對(duì)外部源的依賴(lài)與安全風(fēng)險(xiǎn)。
核心優(yōu)勢(shì):
- 自動(dòng)化初始化流程;
- 支持平臺(tái)差異化索引;
- 國(guó)內(nèi)鏡像加速下載;
- 易于部署與維護(hù)。
現(xiàn)在就開(kāi)始搭建屬于你自己的私有 PyPI 倉(cāng)庫(kù)吧!
GitHub 參考資源:
- Devpi 官方文檔: https://doc.devpi.net
- Top PyPI Packages 統(tǒng)計(jì): https://hugovk.github.io/top-pypi-packages/
- 阿里云 PyPI 鏡像: https://mirrors.aliyun.com/pypi/simple/
到此這篇關(guān)于使用Docker搭建私有PyPI鏡像倉(cāng)庫(kù)的完整步驟教學(xué)的文章就介紹到這了,更多相關(guān)Docker搭建私有PyPI鏡像倉(cāng)庫(kù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Docker安裝并使用Mysql的詳細(xì)教程(實(shí)測(cè)可用!)
在日常的工作中經(jīng)常會(huì)需要將數(shù)據(jù)存在服務(wù)器,經(jīng)常用到的數(shù)據(jù)庫(kù)是mysql,下面這篇文章主要給大家介紹了關(guān)于Docker安裝并使用Mysql的詳細(xì)教程,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-01-01
docker常用命令及設(shè)置開(kāi)機(jī)自啟方式
這篇文章主要介紹了docker常用命令及設(shè)置開(kāi)機(jī)自啟方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06
docker容器添加對(duì)外映射端口的實(shí)現(xiàn)
本文主要介紹了docker容器添加對(duì)外映射端口的實(shí)現(xiàn) ,從而實(shí)現(xiàn)容器與外部網(wǎng)絡(luò)的通信,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-09-09
Docker啟動(dòng)RabbitMQ實(shí)現(xiàn)生產(chǎn)者與消費(fèi)者的詳細(xì)過(guò)程
這篇文章主要介紹了Docker啟動(dòng)RabbitMQ,實(shí)現(xiàn)生產(chǎn)者與消費(fèi)者,通過(guò)Docker拉取鏡像并啟動(dòng)RabbitMQ,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02

