关于在内网服务器上搭建Python和Perl环境的两个问题

PythonPerl最为强大的高级脚本语言,其中很大一个亮点就是可以实现各种扩展。这两个语言在目前网络上都有大量的扩展模块。我们可以随时使用来简化我们的工作。

在开发过程,大家都习惯了两个语言的一些包管理工具,需要什么模块,直接一个命令就搞定了,例如Python的pip,Perl的cpan等等。但是在生产环境,或者说正式环境上。我们想安装扩展模块就没这么容易了。在现实环境中,并不像我们做开发测试那样方便通过网络安装模块,一般服务器都是内网隔离的,而且使用的用户都一定的权限设置,这就是说,你无法从网络安装模块,也不能使用系统权限将模块安装到默认路径中。这两个问题从很大程度上让我们再使用pip或者cpan这些工具不再那么方便。为了能更好地在正式环境上使用这些工具,我们需要解决两个问题。

1. 如何离线使用包管理工具安装扩展模块,不需要使用网络,同时完成依赖包的安装;
2. 如何将包安装到非系统权限路径

为了解决上面的两个问题,我们来分别介绍两个语言的解决方法。

离线使用包管理工具安装扩展模块

Python

pipvirtualenvfabric号称Python三大神器。这里pip绝对不是浪得虚名,它的包管理功能是十分强大的,其中一点就是可以离线完成包的安装,包括其自动找到各种依赖包。

在没有外网连接的环境上,如果想安装一些自己常用的模块,这些模块还有一大堆依赖包。这时候我们只能把所有的离线安装包都下载下来,一个个按照顺序安装。这肯定不是个好方法。pip轻松解决了这个问题。
假设我们的开发环境是联网的,而且上面的各种扩展包都是完全安装好的,我们便可以利用这一点来制作一个专属自己的扩展包集合。

在有外网连接的开发环境上,执行

1
2
3
pip list 
pip freeze > requirements.txt
pip install --download path/to/your/package/dir -r requirements.txt

pip list列出当前环境下所有安装好的扩展包,然后使用pip freeze将当前环境下所有的包信息写到了requirements.txt文件中。再以此文件为准,将所有的文件内涉及的模块,下载到自定义的目录当中。下载完成后,可以将这个路径转移到正式环境中。

在正式环境上执行

1
pip install --no-index --find-index=path/to/your/package/dir -r requirements.txt

这时候pip便可以根据requirements.txt文件,从指定文件夹内获取所需要的扩展包,不需要网络就安装到了生产环境下。

pip这一功能绝对算得上是神技能,轻松解决了Python离线安装的问题。

pip的版本要保持最新,否则可能出现安装错误的问题。

Perl

Perl在离线安装这点上显得“笨重”些,目前本人没有找到Perl上像pip那样,可以仅离线下载自己所需的扩展包,Perl目前能做的就是对CPAN做一个迷你的镜像备份。也就是把CPAN上的主要版本都DOWN下来。形成一个本地的,小巧的CPAN,这样来实现离线安装。

虽然说这也是一个方法,但是下载的镜像需要占用一定的空间,有3个G之多。传输和存储多多少少都有些不方便。

要实现此功能的工具叫做minicpan。我们现在自己的开发环境上,例如个人电脑的虚拟机上保持网络通畅,利用cpan或者cpanm先安装CPAN::Mini模块,然后建立一个minicpan所要用到的配置文件,默认为~/.minicpan。在里面写下如下内容

1
2
local: ~/LocalCPAN/minicpan 
remote: http://cpan.hexten.net/

local就是要下载镜像的本地路径。remote是CPAN的远端镜像网址,我们可以通过这个网站选择一个适合自己网络情况的地址。

接下来直接执行命令minicpan,就开始下载迷你镜像了。慢慢等待吧~~

当这个下载完成后,将~/LocalCPAN/minicpan移动到没有互联网连接的机器上。打开cpan,依次执行下列语句

1
2
3
4
5
6
cpan[1]> o conf urllist push file:///home/user/LocalCPAN/minicpan

cpan[2]> o conf urllist
urllist 0 [file:///home/user/LocalCPAN/minicpan]

cpan[3]> o conf commit

这时候,cpan工具的默认下载源便成了本地的路径了。这时再用cpan安装自己所需的扩展包,就可以无须外网连接,离线完成安装了。

注意下载的过程会很漫长。而且有可能因为网络原因导致程序退出。我们要在原来的基础上继续下载时,需要使用minicpan -f命令来继续执行。

将模块安装到非系统权限路径。

Python

将Python的扩展包安装到非系统权限路径中其实很简单,只需在pip或者源代码安装python setup.py install命令时加上--user参数,那么Python会自动将模块安装到~/.local路径下。并将这个路径加入到Python模块的搜索列表。可以说是很方便。

这种方法很省心,但是扩展包却要占用home空间。本人目前没有找到如何将扩展包安装到其他自定义的目录中,并将此目录加入搜索路径。这个以后再慢慢研究。

Perl

在源代码安装时,当用户没有系统权限,可以使用参数将模块安装到自定义的目录。如果使用的是ExtUtils::MakeMaker
方式,使用参数INSTALL_BASE=。如果使用的是Module::Build,则可以使用参数--install_base=

当我们使用cpan安装扩展包时,通过定义cpan配置文件里这两个路径,也可以将扩展包安装到自定义的目录。

1
2
3
4
5
> cpan: o conf
>
> makepl_arg [INSTALL_BASE=/path/to/build]
> mbuild_arg [--install_base /path/to/build]
>

这里有个问题,我们只是将扩展包安装到了自定义的目录中,但是Perl默认的@INC数组中的找不到这个路径的,更不用说路径下的扩展包。这一步我们要做的就是让Perl能够找到自定义的路径,我们可以使用以下三种方法:

  1. 添加系统环境变量PERL5LIB,指向自定义目录,即可将自定义的路径加入到@INC中。
  2. 在Perl源码中使用usr lib 'path/to/perl/module'
  3. 在启动perl命令时,使用-l参数。例如perl -l path/to/perl/module test.pl此方式一般用于测试新模块

以上方法都是手动更改路径,其实还有一个更加智能的方法。在CPAN上有一个local::lib模块。使用这个模块可以根据自定义路径,自动管理各种Perl所需要的系统变量和@INC数组。具体安装使用方法可以参考其官方网站local::lib

参考资源: