利用pyinstaller打包python项目发布到线上

问题抛出点

3月份搭建的python web框架,在一个项目中落地后,在部署的时候还是稍显麻烦,虽然用了pipenv的方式管理依赖,但是在线上的时候还得要求线上环境可以连外网,但是一般线上环境会有一些隔离,而且上线前也会有一些python依赖要去安装,这其实还不够极致。所以需要一种能把python项目打成bin文件的方式,所有依赖的包都集成在这个bin文件中,直接上线bin文件就可以了。如果这个能实现其实就解决了目前我的需求了。

pyinstaller

带着这个出发点就去找解决方法,工具其实挺多,我选择了pyinstaller这个工具作为第一个尝试目标。

环境特点:首先我们用的pipenv管理应用的,每个应用其实都有一套独立的虚拟环境,所以这个时候pyinstaller不能安装到全局,我刚开始使用的pip3去安装到了全局,然后用pyinstaller命令去打包项目,发现使用pipenv管理的包不能被打包bin文件里面去,运行的时候就报依赖包缺失。所以一定要用pipenv install -d pyinstaller去安装到项目的虚拟环境中。

见文章:pipenv and pyinstaller not packaging dependencies

但是解决上面依赖没进bin文件的问题后,我们打完的bin文件运行的时候仍然报了如下的错

➜  test git:(master) ✗ ./dist/test
Traceback (most recent call last):
  File "main.py", line 1, in 
    from sanic import Sanic
  File "/Users/doctorq/.local/share/virtualenvs/test-o9LtdYv1/lib/python3.7/site-packages/PyInstaller/loader/pyimod03_importers.py", line 627, in exec_module
    exec(bytecode, module.__dict__)
  File "site-packages/sanic/__init__.py", line 1, in 
  File "/Users/doctorq/.local/share/virtualenvs/test-o9LtdYv1/lib/python3.7/site-packages/PyInstaller/loader/pyimod03_importers.py", line 627, in exec_module
    exec(bytecode, module.__dict__)
  File "site-packages/sanic/app.py", line 19, in 
  File "/Users/doctorq/.local/share/virtualenvs/test-o9LtdYv1/lib/python3.7/site-packages/PyInstaller/loader/pyimod03_importers.py", line 627, in exec_module
    exec(bytecode, module.__dict__)
  File "site-packages/sanic/config.py", line 4, in 
ModuleNotFoundError: No module named 'distutils'
[84155] Failed to execute script main

缺少distutils,这个问题折腾了两天,总算找到解决方法,见文章:distutils not included with latest virtualenv,具体解决方法就是修改你虚拟环境下的PyInstaller/hooks/pre_find_module_path/hook-distutils.py,然后打包的就没问题了。

最后给出打包命令:pipenv run pyinstaller -F main.py -n test

  • -n 打包后bin文件的名称
  • F 打包成一个单独文件

更新框架

不更,这种需要每次都手动更改的方式,暂时不推广,太恶心。等啥时候pyinstaller修复这个问题,再说吧,但至少pyinstaller打bin包的方式还是可行的~暂时还用源码部署着吧

你可能感兴趣的:(策略架构)