请教一个生产环境 Python 多版本管理的问题

2021-09-11 03:14:19 +08:00
 haishenmao
目前场景是这样的:
服务需要部署在物理机上(不希望服务进容器,这个是客观限制没法变动)
物理机均为较旧版本的 Ubuntu Server (比如 14.04 、16.04 ,可以尝试用过 deadsnake 的 ppa 里的包,是可以正常部署的)
不能对原有的 python 环境产生破坏性,必须独立于原有的 python 环境( Ubuntu 系统工具中存在一些依赖自带 python2 、3 的工具,尝试过强制更新,会造成一些无法预料的问题)
pip 需要独立出来 (python3.4 、3.5 能用的 pip 版本的 setuptools 不兼容较新的包,使用 Pipenv 进行包管理)


项目使用的特性至少需要依赖于 python3.7 以上(需要用些 asyncio 的新功能),之前尝试在 14.04 3.4 的环境下使用 pipenv ( 16.04 可以正常用 pipenv ),均会有至少 python3.5 的版本要求限制,所以需要一套完全独立于系统的 python 和 pip 环境。

项目的开发环境都是使用 pipenv+pyenv 进行多版本、pip 隔离的,所以希望尽量可以在线上使用 pipenv 。

目前初步想法是编好一套完全独立于系统的 python 环境丢在专门的目录下,然后写一个独立的环境变量文件,启动使用 shell 脚本启动(这样内部运行时会携带进去专用指向的 python 环境参数),不知道这样是否可行?或者大家有什么更好的办法吗?
3538 次点击
所在节点    Python
23 条回复
noqwerty
2021-09-11 03:52:25 +08:00
miniforge 解君愁
jeeyong
2021-09-11 04:28:28 +08:00
pyenv
Varchar
2021-09-11 06:21:56 +08:00
pyenv 简单方便
XiLingHost
2021-09-11 08:12:18 +08:00
docker
ila
2021-09-11 08:24:14 +08:00
前面几位看清楚了条件限制吗
nuistzhou
2021-09-11 10:10:12 +08:00
我觉得你的想法可行,pip 啥的,也可以直接去对应的目录里执行
ClericPy
2021-09-11 11:51:50 +08:00
之前也被这个困扰过, 所以到处找绿色版 Python 解释器... 还想过编译成可执行但是又慢又不好用就放弃了

最后我这边还是找运维同学在专门的 prefix 目录下面装了个 Python3.8 解释器+软连接 python3.8 用, 至于环境隔离

1. venv 基本就隔离干净了

2. 考虑到打包又不想用 venv, 所以用的 python3.8 -m pip install -t /python_venvs/product _name -r requirements.txt 单独安装到我自己的目录里, 用的时候在 sys.path 加上它. 后来还考虑了 NAS 盘
2.1 再后来感觉每次这么折腾有点麻烦, 有的机器还不能请求外网, 就模仿 shiv 写了个叫 zipapps 的轮子, 其实不是很复杂的东西就是把依赖都打包到 zip 文件里依靠 zipimport 和 Python 可以直接运行 zip 里的代码这两个特性把依赖打包到一块, 发布以后执行的时候依赖都带好了. 只能说凑合用了

总之我不喜欢 docker, 现在正在往 Serverless 上迁
walpurgis
2021-09-11 12:24:10 +08:00
不希望用容器的理由是什么
ulosggs
2021-09-11 12:29:33 +08:00
这不是很常见的需求吗?
anaconda
Jwyt
2021-09-11 13:01:00 +08:00
可以看下 github/pdm-project
VIVVACI
2021-09-11 13:45:42 +08:00
我不太理解为什么一定要在物理机上面而不用容器,ipc 直接 host,服务通信也有端口映射,实在不行网络也设为 host,明明直接配置好之后拉起来就完事了。
ClutchBear
2021-09-11 13:56:58 +08:00
每个项目一个 user,
每个 user 下安装一个相应版本的 miniconda.
这样互相没有任何干扰了
shuimugan
2021-09-11 13:58:32 +08:00
pyenv 每一个 python 版本安装之后就是在 home 目录存放的,在当前目录里使用绝对路径 python -m venv 就能得到一个 venv 文件夹,里面有指定的 python 版本和隔离的 pip 包。

后续 python 和 pip 命令都使用 venv 文件夹里的,就能做到多 python 版本多 pip 包隔离了
jaredyam
2021-09-11 18:23:36 +08:00
事实上我相信大部分案例都是选择上容器,这样你爱咋折腾咋折腾。

感觉你说得稍微有点乱,所以也没看出来当前面对的主要问题是什么。你起码多列举几个包管理器说说它们哪有问题啊,我现在就没看出来最基础的 venv 在你的场景里有什么问题。

```bash
python -m venv .venv
```

至于在项目目录下自动启动所属环境,了解下 direnv ?
ruanimal
2021-09-11 22:59:24 +08:00
用 miniconda 的 env 隔离吧
haishenmao
2021-09-11 23:57:00 +08:00
@VIVVACI #11
@walpurgis #8
@jaredyam #14

简单来说就是 这个服务是 A 业务线 用来统计数据的,有且仅有这一个服务是使用 python 编写的,但是 registy 是公用的。A 业务线 有自己专用的 CI/CD 工具用来在物理机部署服务,且由内部管理而且不使用容器。
如果按照合规的标准流程来就要给编好的 image 丢到公用的 registy 上并走一大套又臭又长的交叉审批流程,对于这种相对来说无关紧要的服务,每次发版都会非常麻烦,但是不这样做后续就不好管理。

原则来说我也是希望这些服务都滚进容器,但是这是客观情况限制,不想掺和这些事。



@ulosggs #9
@ruanimal #15
试了下这个方案 感觉还不错,谢谢解答
xchaoinfo
2021-09-13 09:14:30 +08:00
@ClericPy 赞同这个方案, 我们有项目就是用类似的方案做的
zhengxiaowai
2021-09-13 10:33:16 +08:00
pipenv 不适用与生产环境,请使用更轻量级的 virtualenv,起码能没人会删除你代码目录下的文件
julyclyde
2021-09-13 14:22:51 +08:00
"python 本身“还是应该用工具来管理,确保可原样重建
如果你仅仅是打包一个当时的版本,很快就会遇到各种外部依赖导致的问题
calmzhu
2021-09-13 22:36:40 +08:00
@haishenmao
继续推荐容器,不用镜像分发,当作虚拟环境管理器就可以了。

跑起来主进程挂个 cat.更新文件就行了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/801160

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX