利用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 <module>
    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 <module>
  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 <module>
  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 <module>
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包的方式還是可行的~暫時還用源碼部署着吧

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章