用树莓派打造便携式 PyPI 服务器

1eca8c49e2d537e308bffc3e790dfa90.jpeg

在这篇文章中,我将讨论如何将 PyPI 仓库克隆到 Raspberry Pi 上并提供内容,以便让连接的设备在没有互联网连接的情况下通过 pip install命令安装依赖包。

目标

创建自己的PyPI镜像有很多方法,我的方法现在可能对所有人都适用。我对这个项目的目标是:

  • 做这个项目的硬件必须是可负担得起的(<=100美元)。

  • 在客户端电脑上必须有很少或没有设置要求。

我决定使用Raspberry Pi 4,用200Gb的SD卡进行存储。用 minirepo来克隆PyPI, pypiserver来提供软件包, nginx来创建反向代理。

创建本地PyPI服务器有四个步骤:

1、下载并安装操作系统和系统工具 2、配置Raspberry Pi作为一个WiFi热点、DHCP和DNS服务器 3、克隆/下载PyPI软件包 4、配置一个网络服务器,将下载的软件包提供给连接的客户。

下面我将详细解释上述步骤。

一、下载并安装操作系统和系统实用程序

Raspberry Pi是一种小型信用卡大小的计算机,售价至少为35美元。在这个项目中,我使用了Raspberry Pi 4,但其他型号也应该可以使用。Raspberry Pi 3和4型号有内置的WiFi适配器,这使得将Raspberry Pi设置为WiFi热点或接入点的工作比使用外部无线适配器时更简单。

要开始使用,请下载并安装Raspbian。Raspbian是一个基于Debian的轻量级操作系统,为Raspberry Pi进行了优化。为了作为接入点工作,Raspberry Pi将需要安装接入点软件,以及为连接设备提供网络地址的DHCP服务器软件。

接下来,在配置Raspberry Pi之前,下载所有你需要的实用程序和软件包。

你需要以下软件包:

dnsmasq - DNS和DHCP服务器软件 hostapd - 接入点软件 minirepo - 用于克隆PyPI,供离线使用。pypiserver - 从克隆的PyPI包中创建一个索引 nginx - 一个网络服务器

要安装这些软件包,请运行这两条命令:

$ sudo apt install dnsmasq hostapd nginx $ pip install minirepo pypiserver

二、配置Raspberry Pi的WiFi热点、DHCP和DNS

这一步的目标是配置一个独立的网络作为服务器,所以Raspberry Pi需要有一个分配给无线端口的静态IP地址。为了配置静态IP,编辑dhcpcd配置文件。

$ sudo nano/etc/dhcpcd.conf

添加以下内容:

d63492b61755e4b5a7d4f34e20fdf8ef.jpeg

配置DHCP

dnsmasq设置中的很多默认设置都是不必要的。创建一个新的配置文件:

$ sudo mv/etc/dnsmasq.conf/etc/dnsmasq.conf.orig $ sudo nano/etc/dnsmasq.conf

添加以下配置:

316df99d53388b6fff23f955362d6b26.jpeg

这为通过无线接口 wlan0连接的客户设置了DHCP。第二行告诉DHCP服务器(dnsmasq)监听来自你在上一步设置的静态IP的连接。下一行告诉DHCP提供IP地址 192.168.4.2192.168.4.30,租用时间为24小时。

创建一个接入点

接下来,配置接入点软件(hostapd):

$ sudo nano/etc/hostapd/hostapd.conf

添加以下内容:

27584e5745ca7503b601b0564f4bb0e6.jpeg

在写有 sssidwpa_passphrase的地方添加你自己的网络名称和网络密码。

告诉系统在哪里可以找到这个文件,打开 hostapd的配置文件。

sudo nano/etc/default/hostapd

找到带有 #DAEMON_CONF的那一行,并把它替换成这样:

DAEMON_CONF="/etc/hostapd/hostapd.conf"

添加路由和伪装

编辑 /etc/sysctl.conf并取消对这一行的注释。

net.ipv4.ip_forward=1

eth0的出站流量添加一个掩码。sudo iptables-t nat-A POSTROUTING-o eth0-j MASQUERADE

保存新的规则: sudo sh-c"iptables-save > /etc/iptables.ipv4.nat"

编辑 /etc/rc.local,在 "exit 0 "上面添加以下内容,以便在启动时安装这些规则。

iptables-restore</etc/iptables.ipv4.nat

如果你决定以后共享互联网连接或在Raspberry Pi上设置一个网桥,这一点很重要。

Raspberry Pi应该已经准备好作为一个接入点工作了。如果你直接连接到它,现在是启用SSH的好时机。重新启动Raspberry Pi,测试是否一切正常。

使用一个不同的支持WiFi的设备,如手机或笔记本电脑,扫描新的无线网络。如果一切都很顺利,你应该看到你上面创建的WiFi网络。尝试连接到它。

三、克隆PyPI

在本节中,你将看到如何克隆PyPI并配置以下软件包。

minirepo pypiserver nginx

Minirepo

Minirepo是一个命令行程序,从PyPI.org下载软件包,这样你就可以在没有互联网的情况下使用pip。安装它的最简单方法是使用pip。

$ pip install minirepo

第一次执行时, minirepo会问你本地仓库的路径(它应该把下载的软件包保存到哪里),在Linux中默认为 ~/minirepo。一个 JSON 配置文件被创建并保存为 ~/.minirepo,你可以根据自己的喜好进行编辑。

有许多克隆PyPI的替代方案,但我使用了minirepo,因为它允许你有选择地下载一个镜像,例如,只下载Python 3的所有源代码。在写这篇文章的时候,整个PyPI资源库大约有1TB,但通过使用选择性下载,我能够把它降低到120GB左右。以下是我在这个项目中使用的配置。

65779c7bf91fc2f338c3c11a0ba8562f.jpeg

上面的配置下载了Python 3的源代码,并将包的类型限制为 sdistbdist_wheelbdist_egg包。使用这种方法的缺点是,一些不符合过滤条件的软件包将不会被下载。

克隆PyPI需要很长的时间,所以你要让它在后台运行。

Pypiserver

在这一点上,你应该把PyPI镜像到你的电脑上。我的本地PyPI镜像有200000多个软件包。在我们进行下一步之前,有必要了解什么是 pip以及它是如何工作的。

Pip是最流行的安装Python软件包的工具,也是现代版本的Python所包含的工具。它提供了从PyPI和其他Python软件包索引中查找、下载和安装软件包的基本核心功能,并且可以通过其命令行接口(CLI)纳入广泛的开发工作流程。

Pip支持从以下地方安装软件包。

  • 使用需求指定器从PyPI(和其他索引)安装软件包。

  • VCS项目的URL。

  • 本地项目目录

  • 本地或远程源文件

由于你已经克隆了PyPi软件包到本地仓库,pip可以直接从你刚刚下载的本地PyPI镜像中安装这些软件包。不过这不是本文的目的。这里的目标是允许远程客户端连接到Raspberry Pi并通过网络下载软件包。这就是pypiserver的作用。

pypiserver,将提供本地软件包索引,允许pip通过网络找到你的软件仓库中的软件包。

首先,测试一下它是否有效。

$ pypi-server-p8080~/minirepo&# Will listen to all IPs.

注意,在运行时,运行它的命令是 pypi-server而不是 pypyserver

在这里,你要启动 pypiserver 并在 8080 端口运行它。它将找到 minirepo文件夹中的软件包。这个进程将一直在后台运行,直到你杀死它或关闭Raspberry Pi。我稍后会告诉你如何启动它。

如果你在浏览器中访问你为Raspberry Pi设置的8080端口的静态IP,你应该看到一个与下面类似的信息。

50b4765ece6c55f2cfd289bdb0048f56.jpeg

你现在可以从本地软件库安装。

pip install--index-url http://localhost:8080/simple/

或者,从客户电脑上安装。

pip install--index-url http://192.168.4.1:8080/

如果你在一个没有HTTPS的远程URL上安装了 pypiserver,你会收到pip发出的 "不受信任 "的警告,敦促你添加--受信任的主机选项。

pip--trusted-host192.168.4.1install--index-url http://192.168.4.1:8080/

还有一个更短的方法。pip--trusted-host192.168.4.1install-i http://192.168.4.1:8080/

总是在命令行上指定本地的pypi URL和受信任的主机标志会很麻烦。如果你想总是从你自己的镜像中安装软件包,在你的主目录或虚拟环境中创建这个 pip 配置文件。

0662c4b1b8fb5a03858f56f2171b50a1.jpeg

主目录:

  • 在Unix和macOS上,主目录文件是: $HOME/.pip/pip.conf

  • 在Windows中,该文件是: %HOME%\pip\pip.ini

在虚拟环境中:

  • 在Unix和macOS中,文件是 $VIRTUAL_ENV/pip.conf

  • 在Windows上,该文件是: %VIRTUAL_ENV%\pip.ini

我建议把这个配置文件放在虚拟环境中。

四、设置一个网络服务器来传递包裹

默认情况下, pypiserver在每次传入的HTTP请求发生时都会扫描整个软件包目录。当像我们在这个例子中提供大量的软件包时,这可能会导致显著的速度下降。

一个更快地提供文件的方法是把 pypiserver放在一个反向代理后面,并启用你的网络服务器的内置缓存功能。在这篇文章中,我将使用nginx,但你可以自由地使用任何你喜欢的网络服务器。

在nginx中设置一个新的虚拟主机

创建一个文件 /etc/nginx/sites-available/cheeshop.com。为了本文的目的,我将新的虚拟主机称为cheeshop.com。

运行 $ sudo nano/etc/nginx/sites-available/cheeshop.com并添加以下内容。

28474e8940b1a946f27304719c662598.jpeg

配置的第一部分指示 nginx 创建一个 10GB 的缓存,该缓存将保持活动状态 2 小时。上游 pypi 部分负责从运行在端口 8080 上的 pypiserver 提供内容。CheeseShop 是 Python Package Index 的秘密代号,这就是我将服务器命名为那个的原因。您可以使用任何您喜欢的名称或 IP 地址。

服务器部分指定端口 80 将用于传入的 HTTP 连接,并将这些请求转发到 pypi 服务器。

我不拥有 cheeseshop.com 域名,但我可以使用它,因为我们正在创建一个无法访问 Internet 的独立网络。为了让客户端计算机能够连接到 cheeseshop.com,您需要告诉 DNS 服务器如何解析它。稍后会详细介绍。

要启用这个新的虚拟主机,您需要创建一个指向您刚刚在 /etc/nginx/sites-enabled/ 文件夹中创建的配置文件的符号链接:

$ sudo ln-s/etc/nginx/sites-available/cheeseshop.com/etc/nginx-sites-enabled/

这样做将启用新的虚拟主机。通过运行检查一切正常 sudo nginx-t.如果一切顺利,那就太好了!接下来,要对 DNS 进行小的更改以将 cheeseshop.com 域映射到 IP 地址。

打开 /etc/hosts并为新创建的 cheeseshop.com 域添加一个条目:

16834000a675901543db5c154478d0b0.jpeg

主机文件包含域到 IP 地址的映射,可帮助计算机为您提供正确的内容。Dnsmasq 将在启动时检查此文件,因此最好重新启动它:

sudo service dnsmasq restart

也重新启动 nginx 以取得良好的效果:

sudo service nginx restart

假设一切顺利,您应该能够使用主机名从客户端计算机安装 Python 包,而不是现在使用 IP。

使用服务器

要对此进行测试,请连接到 Raspberry Pi 的 WiFi 网络并在客户端计算机上创建一个新的虚拟环境并在虚拟环境中运行以下命令:

pip--trusted-host cheeseshop.com安装-i http://cheeseshop.com django

运行该命令会产生以下输出:

2b713062c95177a09a8a7e81985d8e24.jpeg

启动时启动 pypiserver(可选)

为确保pypiserver 软件在开机时自动启动,创建一个新的Linux 服务并使用 systemd 对其进行管理。

1、创建服务将管理的启动脚本,将其命名为 start-pypi-server.sh。向其中添加以下内容:

1bfc4653ec74c7348e710fda86c46438.jpeg

2、将脚本复制到/usr/bin 并使其可执行:sudo cp start-pypi-server.sh/usr/bin/start-pypi-server.sh sudo chmod+x/usr/bin/start-pypi-server.sh

3、创建一个单元文件来定义一个systemd服务。将其命名为 pypiserver.service

b55eb5f8519e146029b876214065fb18.jpeg

这定义了一个基本服务。ExecStart 指令指定将运行以启动服务的命令。

4、将单元文件复制到 /etc/systemd/system并赋予权限:sudo cp pypiserver.service/etc/systemd/system/pypiserver.service

sudo chmod644/etc/systemd/system/pypiserver.service

启动并启用服务

1、创建单元文件后,您可以测试服务:

sudo systemctl start pypiserver

2、查看pypiserver服务状态:

sudo systemctl status pypiserver

这将产生类似这样的输出:

75dc34c32590dcf7b7e78d1da9ae8ac7.jpeg

3、停止或重启服务:sudo systemctl stop pypiserver sudo systemctl restart pypiserver

4、最后,使用 enable命令确保服务在系统启动时启动:

sudo systemctl enable pypiserver

结论

我们已经了解了如何在 Raspberry Pi 上创建自己的本地 PyPI 克隆。你学会了如何

  • 将 Raspberry Pi 设置为接入点

  • 将 Raspberry Pi 设置为 DHCP 和 DNS 服务器

  • 克隆 PyPi

  • 使用网络服务器提供克隆的包。

我这样做是为了证明可以离线运行类似 PyPI 的概念。我确信有更好或更有效的方法可以做到这一点。如有任何建议或批评,请在下方发表评论。谢谢阅读。

99e13c399a483b06caaef7096fa52b80.jpeg

- 点击下方阅读原文加入社区会员 -

猜你喜欢

转载自blog.csdn.net/BF02jgtRS00XKtCx/article/details/128179725
今日推荐