Python with docker 生產環境準備 – 初試啼聲
Docker Store上已經有提供許多指定版本的Python環境(連結)
因為對於Dockerfile自動化的不可掌控性高,因此我考慮先手動安裝過一次
相關步驟是:
在我本機linux vm的環境
1.安裝libray/python specific version image
bash進去
2.pip3 requirements.txt
3.創建對應app目錄,提供外部volumn掛載對應
4.加入執行語法啟動images除錯,直到排除環境因素(例如import相關平行目錄的module)
5.若正常,就commit一版,backup image到 dev server的vm 載入啟動
看看是否這樣可以無縫deploy~
首先先取得docker image
sudo docker pull python:3
依官網說明,python:3是3.5.3的版本(我開發是3.5.2,我猜不會有問題)
都抓好以後,啟動這個images bash進去看看
$ sudo docker run -i -t 955 bin/bash
root@46fe81cdc4b7:/#Python 3.6.1 (default, Jul 8 2017, 05:00:20)
[GCC 4.9.2] on linux
Type “help”, “copyright”, “credits” or “license” for more information.
>>>
靠腰…怎麼是3.6.1的版本,應該是python:3.5版號才對…
重跑一次後,我發現,原來這個library/python的image也是透過組裝的方式集合而成,所以先前已經載過的linux核心(估計1xx MB)就不用再重新下載了
這一次跑的非常之快,進去後,看一下python -V,Python 3.5.3沒錯了
這個原生環境就有apt-get了,但若要裝一些像是nano 編輯器之類的,就要先apt-get update,否則會無法找到package
接著,我先透過requirements.txt安裝相關檔案
requirements.txt內容
若要執行一次套件安裝,就下以下指令
pip install –no-cache-dir -r requirements.txt
一般來說,linux原生環境是有分python2以及 python3,當執行pip的時候要分別走pip或pip3,否則會版本錯誤
同理,啟動程式的時候,也要決定是python or python3,而透過docker啟動的環境則python預設就會是你的版本,所以你這次要用python3也會找不到環境
同場加映,先前在同時有python2、python3的環境安裝套件的時候出現了錯誤訊息
Command “python setup.py egg_info” failed with error code 1 in /private/var/folders/r4/bkv_4t9s4r140pjkgv6lsq8w0000gn/T/pip-build-cdxcssp9/mysqlclient
因此需要安裝mysqlclient套件在python3上的話,請先執行:連結
sudo apt-get install python-dev python3-dev sudo apt-get install libmysqlclient-dev pip install pymysql pip install mysqlclient
在這個安裝套件的過程中,cassandra-driver安裝的有點久,先耐心等候,以免前功盡棄…
全安裝好了以後,真的覺得這些環境準備的真的很佛心,讓我們真的不用考慮python2、3相容性的問題
接著快點存檔,把這個image commit記錄起來
sudo docker commit -m “python3.5 install requirements.txt” -a name ab8 python3-app:v1
接著就是要掛載我們的app程式來試試看
python-app目錄下有這些檔案,主要的檔案是在meso_collection_apiserver裡面
所以我預計啟動containner的指令如下:
sudo docker run -it -v ~/python-app:/usr/src/app -p 40402:40402 8e2 python /usr/src/app/meso_collection_apiserver/servers/grpc_server.py
爆出來的Error明顯是Module參考問題
Traceback (most recent call last):
File “/usr/src/app/meso_collection_apiserver/servers/grpc_server.py”, line 25, in <module>
from meso_collection_apiserver.services.main_data_transfer_service import MainDataTransferService
ImportError: No module named ‘meso_collection_apiserver’
我們原始的程式是:
我google大神了一下,發現可以透過加入sys.path解決這個狀況
因此我在使用的module前面,加入了sys.path.append(“/usr/src/app”)
重新跑起來看看,終於跑起來了,即然可以跑,我們可以直接背景執行(改為-d)
sudo docker run -d -v ~/python-app:/usr/src/app -p 40402:40402 8e2 python /usr/src/app/meso_collection_apiserver/servers/grpc_server.py
但我立即測試發現無法通訊,看起來是ip binding的問題嗎?我猜想因為我程式binding在debug的時候綁的ip是localhost
因此我想到一招,就是透過/etc/hosts來綁定到指定的server name
sudo docker -it exec /bin/bash
註:連到container後 ,先打入以下語法,以免不能使用nano
export TERM=xterm
root@c2a240882504:/# nano /etc/hosts
加入下面這行
172.17.0.5 python-app-docker
restart後,立即開啟rpc-client試連這個剛剛建立好的container的服務看看,結果還是失敗…telnet port還是被拒絕,看來在grpc這邊不論是server端還是client端,ip:port都還必須指定同樣具體的ip,且無法給定hostname,我還要再研究看看。直接先公佈解法其一,python程式段直接綁定docker container的ip,我們可以用python語法查找本機ip(連結)。這邊我陸陸續續試過幾組,若本機server、本機client,同一台主機的話是可以使用[::]:40402 ,若是隔一層的vm,那就指定到vm的ip,若是vm內又加一層docker,所以我們不可能每次都這樣調整程式,適必要動態取得本機ip,示例如下:
這下跑一下grpc測試案例,終於通了
但是取得ip在vm的環境下有點小風險,若有多網卡的時候,還必須注意取到的介面是哪一張
不過至少這樣改寫後,ip在預設情況下是可以work的,離一鍵佈署,看起來愈來愈近了
今日時候不早了,待日後分曉
2 Replies to “Python with docker 生產環境準備 – 初試啼聲”
改天我也來照你步驟try try