刘耀杰·言

探索技术与生活的交叉点

← 返回博客

通过 Docker Compose 部署私有 PyPI 仓库

在企业级环境中,Python 依赖管理不仅影响开发效率,更直接关系到部署稳定性与可控性。本文将基于 Docker 搭建一套可离线、可扩展、可高可用的依赖仓库方案。

通用 #DevOps#Docker#Python#私有仓库#依赖管理#General

前言

在企业级环境中,Python 依赖管理不仅影响开发效率,更直接关系到部署稳定性与可控性

公网受限、依赖丢失、版本不一致等问题,使得私有 PyPI 仓库成为必备基础设施

本文将基于 Docker 搭建一套可离线、可扩展、可高可用的依赖仓库方案,满足企业级交付与运维需求


⚠️注意

文件中所有内容要根据自己的情况修改,比如说 image、/data地址、端口号、networks、硬件资源等;


环境准备

安装 Docker

具体安装 Docker Docker-compose 请看过往文章

创建项目目录

mkdir /data/workspace/install-Pypi && cd /data/workspace/install-Pypi

创建 Packages 目录

用于存放你手动传进来的依赖包

mkdir -p packages

镜像准备

docker pull pypiserver/pypiserver:latest

准备文件

编写 docker-compose.yml 文件

cd /data/workspace/install-Pypi && vim docker-compose.yml
version: '3.8'

services:
  pypiserver:
    image: pypiserver/pypiserver:latest
    container_name: pypiserver
    restart: always
    ports:
      - "8080:8080"
    volumes:
      - ./packages:/data/packages
    command: -P . -a . /data/packages

启动服务

docker-compose up -d

测试服务

要确保你仓库里有依赖,临时拉取测试(假设内网 IP 是 192.168.1.100)

pip install <你的依赖包> -i http://192.168.1.100:8080/simple/ --trusted-host 192.168.1.100

获取并存放依赖(两种情况)

一、有网情况

由于机器有外网,我们直接将官方截图中要求的依赖,下载并自动存放到私服的 packages 目录下

pip download -r requirements.txt \
  --only-binary=:all: \
  --find-links ./packages \
  --dest ./packages

存放说明:命令执行完毕后,所有的 .whl 文件会直接存放在 /data/workspace/install-Pypi/packages 目录中,由于 Docker 的 volume 映射机制,pypiserver 容器会实时、自动识别这些新加入的依赖包,无需任何重启操作


二、无网情况

在一台能上网的 Linux 机器上执行以下操作

⚠️ 企业级避坑指南(极其重要): Python 的 .whl 依赖包是分操作系统的。如果你用来下载依赖的有网机器(例如 Mac 或 Windows)与你的内网部署服务器(Linux X86 或 ARM64)架构不同,直接下载的包传到内网是装不上的!

强烈建议: 找一台与你内网服务器操作系统和架构完全相同的有网 Linux 虚拟机(比如都是 CentOS 7 X86_64 或 Ubuntu 22.04 ARM64),在这台上执行以下下载操作。如果实在条件不允许,后续命令中我会教你怎么强行指定平台

在有网的机器上,打开终端,创建一个干净的目录,避免和其他文件混淆

# 创建一个名为 dify-offline-download 的目录
mkdir -p /root/dify-offline-download

# 进入该目录
cd /root/dify-offline-download

将你需要安装的那个 requirements.txt 文件,上传或拷贝到刚才创建的 /root/dify-offline-download 目录中

# 查看确认文件存在
ls -l requirements.txt

只下载编译好的二进制 .whl 包,不下载源码,把它们全部存放到当前目录下的 wheels 文件夹里

pip download -r requirements.txt --only-binary=:all: --find-links ./wheels --dest ./wheels
(等待命令跑完,期间屏幕会疯狂滚动,提示 Saved ./wheels/xxxx.whl,不要中断它,直到出现 Successfully downloaded…)

⚠️注意:

进阶提示(如果你只能用 Mac/Windows 下载给内网 Linux 用): 你必须在命令后面强制指定平台(以目标服务器为 Linux X86_64 为例): pip download -r requirements.txt —only-binary=:all: —find-links ./wheels —dest ./wheels —platform manylinux2014_x86_64 —python-version 3.10 —implementation cp —abi cp310 (如果架构一样,请忽略这条进阶提示,直接用上面标准的即可)

下载完成后,wheels 文件夹里会有几十上百个文件,千万不要一个一个零散地传,极易丢失,我们把它打成一个 .tar.gz 压缩包

# 还在 /root/dify-offline-download 目录下执行:
tar -czvf dify-dependencies.tar.gz ./wheels

在无网环境的操作(解压与入库)

将物理搬运进来的依赖压缩包解压,并移入专属目录

# 1. 解压依赖包(会解压出一个 wheels 文件夹)
tar -xzvf dify-dependencies.tar.gz

# 2. 将解压出来的所有 .whl 文件,移动到仓库专属的 packages 目录下
mv ./wheels/* ./packages/

# 3. 清理无用的空目录和压缩包(保持企业环境整洁)
rm -rf ./wheels dify-dependencies.tar.gz pypiserver.tar

存放说明:当 mv 命令执行完毕,依赖包落入 /data/workspace/install-Pypi/packages 目录的瞬间,pypiserver即完成依赖仓库的加载


文档补充章节

有网环境下的上游源(Fallback)配置

说明:此章节仅适用于【场景一:目标部署服务器具备外网访问权限】, 通过配置 Fallback,私有仓库可以在本地缺失依赖时,自动引导客户端前往指定的公开镜像源(如清华源、阿里源)获取包

方案 A

在服务端(pypiserver)配置单一回源地址,如果你希望私服统一管理一个最稳定的上游源(比如清华源),可以直接修改 docker-compose.yml 中的启动参数

cd /data/workspace/install-Pypi && vim docker-compose.yml

增加 —fallback-url 参数

version: '3.8'

services:
  pypiserver:
    image: pypiserver/pypiserver:latest
    container_name: pypiserver
    restart: always
    ports:
      - "8080:8080"
    volumes:
      - ./packages:/data/packages
    command: -P . -a . --fallback-url https://pypi.tuna.tsinghua.edu.cn/simple/ /data/packages

重启服务使配置生效

docker-compose down
docker-compose up -d

方案 B

在客户端配置多源备用(企业级推荐方案)

由于 pypiserver 的 —fallback-url 只能配置一个上游地址,如果清华源刚好在维护,就会导致下载失败。 在企业实际生产中,为了保证极致的可用性(高可用),我们通常不在服务端配置 Fallback,而是利用 pip 客户端自身的 extra-index-url 特性来实现多源降级

服务端的 docker-compose.yml 保持最干净的状态,不加 —fallback-url

version: '3.8'

services:
  pypiserver:
    image: ucbcvr30j13lrb.xuanyuan.run/pypiserver/pypiserver:latest 
    container_name: pypiserver
    restart: always
    ports:
      - "8081:8080"
    volumes:
      - ./packages:/data/packages
    command: -P . -a . /data/packages

修改部署机器(客户端)的 pip.conf

mkdir -p ~/.pip && vim ~/.pip/pip.conf

写入多源高可用配置

[global]
# 核心:设置超时时间,防止某个源卡死
timeout = 60

# 主源(Primary):你的私有仓库地址,永远最优先从这里找包
index-url = http://192.168.1.100:8080/simple/

# 备用源(Fallback):主源找不到时,依次从以下源寻找
extra-index-url =
    https://pypi.tuna.tsinghua.edu.cn/simple/
    https://mirrors.aliyun.com/pypi/simple/
    https://pypi.org/simple/

# 信任域名:必须将私服 IP(HTTP)和所有涉及的备用源域名加入信任列表
trusted-host =
    192.168.1.100
    pypi.tuna.tsinghua.edu.cn
    mirrors.aliyun.com
    pypi.org

企业级优势说明

采用方案 B 时,依赖解析的控制权交给了 pip 客户端,它会优先去 http://192.168.1.100:8080(本地私服)寻找;

如果找不到,或者私服宕机,它会自动、平滑地切换到清华源;

如果清华源网络波动,它会继续尝试阿里源或官方源;

这是一种极其稳健的“本地优先 + 多云容灾”架构.


评论

回到顶部