根据Linux文件系统层次标准,Python虚拟环境应该放在哪里?

15 投票
1 回答
5971 浏览
提问于 2025-04-18 10:39

标题问的是,在Linux操作系统中,按照Linux文件层次标准(FHS),存放Python虚拟环境的技术上正确的位置应该在哪里。

换句话说,是否可以把Python虚拟环境和你要提供的数据文件放在不同的地方,这样做是否“技术上正确”?

注意:这个问题和我找到的最接近的已问问题不同,因为虚拟环境里包含库、二进制文件、头文件和脚本。

另外,我的代码通常是为了支持可以通过互联网访问的服务。不过,我觉得这并没有显著区分我和那些服务的消费者是同一台服务器上的其他进程的需求。我提到这个细节是为了防止我对评论的回复中出现“网页开发”相关的内容。

作为参考,我使用以下文档作为Linux FHS的定义:http://www.pathname.com/fhs/pub/fhs-2.3.html

我认为流行的virtualenv-wrapper脚本并没有建议正确的做法,因为它默认把虚拟环境存放在用户的主目录。这违反了一个隐含的概念,即这个目录是用来存放用户特定文件的,同时也有“没有程序应该依赖这个位置”的说法。

从文件系统的根目录来看,我倾向于选择/usr(可共享的只读数据)或/srv(系统提供的服务的数据),但在这方面我很难进一步决定。

如果我按照我常用的反向代理的决定,那就意味着选择/usr。Nginx通常会被打包到/usr/share/nginx或/usr/local/nginx中,但根据FHS,/usr应该是以只读方式挂载的。我觉得这很奇怪,因为我从来没有在一个项目中遇到过开发进展缓慢到需要“卸载为只读/重新挂载为可写,卸载/重新挂载为只读”这种操作值得去做。

/srv是另一个可能的位置,但它被描述为“特定服务的数据文件位置”,而Python虚拟环境更侧重于提供服务所需的库和二进制文件(如果不做这种区分,.so文件也应该放在srv里)。而且,多个服务如果有相同的需求,可以共享一个虚拟环境,这就违反了描述中的“特定”细节。

我认为选择正确位置的困难部分在于虚拟环境是一个“环境”,它包含二进制文件和库(几乎像是它自己的小层次结构),这让我觉得在/usr下的某个地方更为常规:

virtual-env/
├── bin          ~= /usr/local : "for use by the system administrator when installing software locally" 
├── include      ~= /usr/include : "Header files included by C programs"
├── lib          ~= /usr/lib : "Libraries for programming and packages"
└── share        ~= /usr/local

在我表达了我的假设和想法后:考虑一个常见的场景,Nginx作为反向代理连接到一个Python应用。把虚拟环境和源代码(例如application.py)放在/usr/local/service_name/下,同时把更常更改的文件(例如‘静态’资源、图片、css)放在/srv下,这样做是否正确?

编辑:为了明确,我知道为什么以及如何使用虚拟环境。我对项目布局或在开发环境中工作并没有困惑。

1 个回答

9

标题问的是,在Linux操作系统中,按照Linux FHS的规定,存放Python虚拟环境的技术上合适的位置是什么?

要记住,Linux FHS并不是真正的“标准”,它只是一些指导原则。只有LSB才把它称为标准,LSB其实就是一堆让支持Linux变得更简单的规则。

/run/sys/proc/usr/local都不属于LFS,但你在大多数Linux发行版中都会看到它们。

对我来说,放虚拟环境的明显选择是/opt,因为这个位置是专门用来安装附加软件包的

不过,在大多数Linux发行版中,只有root用户可以写入/opt,这使得这个选择不太好,因为虚拟环境的主要目标之一就是避免使用root权限。

所以,我建议使用/usr/local(如果你的普通用户账户可以写入的话)——但在你的主目录中安装也是完全可以的。

换句话说,是否“技术上正确”将Python虚拟环境的位置与您正在提供的数据文件分开?

我不太明白你说的“你正在提供的数据文件”是什么意思,但这里有关于虚拟环境的一些规则:

  1. 不要把它们放在源代码管理中。
  2. 维护一个已安装包的列表,并把这个放在版本控制中。记住,虚拟环境并不是完全可移植的。
  3. 保持虚拟环境与源代码分开。

根据以上内容,你应该把虚拟环境与源代码分开。

考虑一个常见场景,Nginx作为Python应用程序的反向代理。将虚拟环境和源代码(例如application.py)放在/usr/local/service_name/下,同时将更动态的文件(例如“静态”资源、图片)放在/srv下,这样做正确吗?

静态资源并不是动态文件,我觉得你可能搞混了术语。

无论如何,你应该这样做:

  1. 创建一个用户账户来运行这个应用程序。
  2. 应用程序文件放在一个由该用户独占的目录下。通常这是/home/username目录,但你也可以把它放在/services/servicename。把虚拟环境放在这个目录下的一个子目录中,使用标准的命名格式。例如,我使用env
  3. 把你的静态资源,比如所有的媒体文件、css文件等,放在一个前端服务器可以读取的目录中。所以,通常你会创建一个www目录或public_html目录。
  4. 确保你为这个应用程序创建的用户账户对这个资源目录有写入权限,这样你才能更新文件。代理服务器不应该对这个目录有执行权限。你可以通过将目录的组更改为与代理服务器用户相同来实现这一点。因此,我会把这个目录放在/home/username//services/servicename下。
  5. 使用进程管理器启动应用程序,并确保你的进程管理器在运行应用程序代码时切换到步骤1中创建的用户。

最后,我要强调的是记录你的过程自动化它

撰写回答