天天看點

如何部署Python Web應用:記錄一次Heroku部署完整過程

   伴随着雲計算的浪潮,國内的雲服務可謂多種多樣,價格雖然不高,但是真正能夠提供永久免費使用的,哪怕有些限制也好,似乎也找不到。

    出于學習/研究/實驗/測試或是真正應用等各種需求,這時我們不妨使用把應用部署到國外的Heroku雲平台上,Heroku的免費版除了其提供的Postgres資料庫有限制之外(小于1萬條記錄的小型資料庫不用付費就可以添加到自己的Web應用上),其它都可以免費使用,這絕對是不二的選擇。

    另外一點來說,Heroku對Python的支援非常良好,是以部署起來會輕松很多,這就省去了許多不必要的麻煩了。

    最近要把應用部署到Heroku上,這裡把完整的部署過程分享給大家。

說明:我使用的作業系統是Ubuntu 15.10,部署的Python Web應用為基于Flask的應用,下面的部署過程都是在該操作環境下進行部署,建議大家也在Linux環境下進行部署,會友善很多。(當然你有Mac Book就更好了,隻是部落客沒錢,用不起啦)

1.準備Git環境

     要想使用Heroku,你的Web應用必須要托管在Git倉庫中,如果你之前一直是使用Git的方式來作開發的,那問題就很容易解決了,相信你很明白其中的道理。如果不是的話,請按照下面我的方法來生成一個Git倉庫,非常簡單。

    很多人覺得使用Git很麻煩,于是就放棄了Heroku平台的使用,這不能不說是一種極大的浪費:

1.首先浪費的是Heroku這麼好的一個平台資源;

2.然後就是放棄了Git這麼優秀的版本控制系統的使用

3.再者說就是放棄了Linux環境的使用。

    其實這些對于開發來說都是非常有幫助的!是以不要覺得麻煩,隻要你以後不是完全做Windows平台的開發,這些你都應該要懂,隻要慢慢習慣了,後面一切就都很自然了。

第一步:安裝Git

    以Ubuntu為例,可以直接使用下面的指令安裝:

1

<code>sudo</code> <code>apt-get </code><code>install</code> <code>git</code>

    當然如果你正在使用的是其它版本的Linux發行版本,相信安裝方法也不難。

第二步:把你的完整Web應用放到一個新的目錄中

    比如這裡我已經有一個開發完整的Web應用,它主要有下面的這些檔案和應用:

2

3

4

5

6

7

8

9

10

11

<code>drwxrwxr-x  6 xpleaf xpleaf 4096  1月 29 16:04 .</code>

<code>drwxr-xr-x 38 xpleaf xpleaf 4096  1月 29 16:01 ..</code>

<code>drwxrwxr-x  7 xpleaf xpleaf 4096  1月 29 03:31 app</code>

<code>-rw-rw-r--  1 xpleaf xpleaf 3295  1月 29 03:31 config.py</code>

<code>-rw-rw-r--  1 xpleaf xpleaf 1083  1月 29 03:31 LICENSE</code>

<code>-rwxrwxr-x  1 xpleaf xpleaf 2391  1月 29 03:31 manage.py</code>

<code>drwxrwxr-x  3 xpleaf xpleaf 4096  1月 29 03:31 migrations</code>

<code>-rw-rw-r--  1 xpleaf xpleaf   25  1月 29 03:13 Procfile</code>

<code>-rw-rw-r--  1 xpleaf xpleaf  376  1月 29 03:31 README.md</code>

<code>-rw-rw-r--  1 xpleaf xpleaf   76  1月 29 03:13 requirements.txt</code>

<code>drwxrwxr-x  2 xpleaf xpleaf 4096  1月 29 03:31 tests</code>

    然後建立一個名為Heroku_pro的檔案夾,并把上面完整的Web應用程式放進去,如下:

<code>xpleaf@leaf:~</code><code>/Heroku_pro</code><code>$ </code><code>pwd</code>

<code>/home/xpleaf/Heroku_pro</code>

<code>xpleaf@leaf:~</code><code>/Heroku_pro</code><code>$ </code><code>ls</code>

<code>app  config.py  LICENSE  manage.py  migrations  README.md  requirements.txt  tests Procfile</code>

    這一步完成!

第三步:在Heroku_pro目錄下生成一個Git倉庫

<code>xpleaf@leaf:~</code><code>/Heroku_pro</code><code>$ git init</code>

<code>初始化空的 Git 版本庫于 </code><code>/home/xpleaf/Heroku_pro/</code><code>.git/</code>

    這時你會發現在目前目錄下多了一個.git的目錄:

<code>xpleaf@leaf:~</code><code>/Heroku_pro</code><code>$ </code><code>ls</code> <code>-a</code>

<code>.   app        .git     manage.py   README.md     tests</code>

<code>..  config.py  LICENSE  migrations  requirements</code>

    這一步完成。

第四步:把目前目錄下的所有檔案都托管到本地Git倉庫

<code>xpleaf@leaf:~/Heroku_pro$ git add .</code>

<code>xpleaf@leaf:~/Heroku_pro$ git commit -m </code><code>"ver1.0"</code>

<code>[master (根送出) a7cea3f] ver1.</code><code>0</code>

<code> </code><code>78</code> <code>files changed, </code><code>3350</code> <code>insertions(+)</code>

<code> </code><code>create mode </code><code>100644</code> <code>LICENSE</code>

<code> </code><code>create mode </code><code>100644</code> <code>README.md</code>

<code> </code><code>create mode </code><code>100644</code> <code>app/__init__.py</code>

<code> </code><code>create mode </code><code>100644</code> <code>app/api_1_0/__init__.py</code>

<code> </code><code>create mode </code><code>100644</code> <code>app/api_1_0/authentication.py</code>

<code> </code><code>......</code>

    Ok,這一步完成。

    關于Git的使用顯然不是這裡要讨論的重點,這裡隻是為沒有用過Git的朋友提供一種臨時的解決方案。

2.注冊Heroku賬戶

    跟目前國内的大多數雲平台一樣,首先你也需要注冊一個賬号,可以在下面的連結進行注冊:

3.安裝Heroku Toolbelt用戶端

    Toolbelt是Heroku的指令行工具,使用該用戶端的好處是,我們完全可以在本地通過指令行操作的方式來管理我們托管在Heroku上的Web應用。

    以Ubuntu為例,參考官方的安裝文檔:

<code>wget -O- https:</code><code>//toolbelt</code><code>.heroku.com</code><code>/install-ubuntu</code><code>.sh | sh</code>

4.登陸Heroku

    在剛剛的Heroku_pro目錄下執行下面的指令,登陸到Heroku上:

<code>xpleaf@leaf:~</code><code>/Heroku_pro</code><code>$ heroku login</code>

<code>Enter your Heroku credentials.</code>

<code>Email: [email protected]</code>

<code>Password (typing will be hidden): </code>

<code>Logged </code><code>in</code> <code>as [email protected]</code>

<code>xpleaf@leaf:~</code><code>/Heroku_pro</code><code>$</code>

    注意登陸成功後的提示:Logged in as [email protected]

    需要注意的是,login指令預設會自動為你目前的主機建立SSH公鑰并上傳,SSH公鑰非常重要,在你後面執行git push指令的時候是必須要用到的,不過不用擔心,heroku的用戶端會自動幫我們處理好。當然你也可以手動上傳,隻需要執行指令:heroku keys:add。

5.使用Heroku用戶端建立app程式

    所謂的app程式其實就是herokuapp.com的一個子域名,當你在Heroku建立了一個名為my-heroku-app-cn的app程式之後,如果你部署成功,你就可以直接通過位址https://my-heroku-app-cn.herokuapp.com來通路你的Web應用,是以名字要注意,不能使用别人已經使用過的。我們下面就來建立一個。

<code>xpleaf@leaf:~</code><code>/Heroku_pro</code><code>$ heroku create my-heroku-app-cn</code>

<code>Creating my-heroku-app-cn... </code><code>done</code><code>, stack is cedar-14</code>

<code>https:</code><code>//my-heroku-app-cn</code><code>.herokuapp.com/ | https:</code><code>//git</code><code>.heroku.com</code><code>/my-heroku-app-cn</code><code>.git</code>

    當然,其實app程式的名字也是可以改的,你隻要登陸官居網,在你的個人資訊頁裡就可以修改。

6.配置資料庫

    Heroku以擴充的方式支援Postgres資料庫,隻是有些限制而已,正如前面所說。這裡我們就使用Postgres資料庫,這也意味着,你需要在你的Web應用源代碼中添加相應的資料庫路徑,這個我們待會再說。

    使用下面的指令配置資料庫:

<code>xpleaf@leaf:~</code><code>/Heroku_pro</code><code>$ heroku addons:create heroku-postgresql:hobby-dev</code>

<code>Creating postgresql-rectangular-17531... </code><code>done</code><code>, (</code><code>free</code><code>)</code>

<code>Adding postgresql-rectangular-17531 to my-heroku-app-cn... </code><code>done</code>

<code>Setting DATABASE_URL and restarting my-heroku-app-cn... </code><code>done</code><code>, v3</code>

<code>Database has been created and is available</code>

<code> </code><code>! This database is empty. If upgrading, you can transfer</code>

<code> </code><code>! data from another database with pg:copy</code>

<code>Use `heroku addons:docs heroku-postgresql` to view documentation.</code>

    出現上面的提示也就說明資料庫配置成功了,關于該資料庫的詳細資訊,你也可以到官網的個人中心進行檢視,裡面有非常詳細的說明,如下:

<a href="http://s1.51cto.com/wyfs02/M01/7A/87/wKioL1arLkPh3tgwAAAyoMoXOPA985.png" target="_blank"></a>

<a href="http://s1.51cto.com/wyfs02/M02/7A/87/wKiom1arLHWxUsiGAABaJNUtBsI656.png" target="_blank"></a>

<a href="http://s1.51cto.com/wyfs02/M02/7A/87/wKioL1arLL7QrszqAAA4cAWiwdE778.png" target="_blank"></a>

    這裡我們需要注意一句話:Setting DATABASE_URL and restarting my-heroku-app-cn... done, v3

    也就是說,Heroku自動為我們剛剛建立的my-heroku-app-cn程式建立了一個名為DATABASE_URL的環境變量,變量的值就是在Heroku平台中該資料庫的路徑位址,這也意味着,如果你想讓你的Web應用部署成功後可以正常連接配接上該資料庫,就必須在你的源代碼中設定資料庫的位址為:DATABASE_URL,僅此而已,其它的Heroku會為我們完成,不用擔心。

7.配置必要的環境變量

    這不是必要的,這取決于你的Web應用的源代碼中是否有擷取系統環境變量的需要,如果有的話,你可以通過下面的方式進行環境變量的設定。

    比如我在我的源代碼的配置檔案中有下面的兩行代碼:

<code>MAIL_USERNAME </code><code>=</code> <code>os.environ.get(</code><code>'MAIL_USERNAME'</code><code>)</code>

<code>MAIL_PASSWORD </code><code>=</code> <code>os.environ.get(</code><code>'MAIL_PASSWORD'</code><code>)</code>

    顯然電子郵件的使用者名和密碼這些敏感的資訊不應該出現在源代碼中,是以我是通過擷取環境變量的值來知道使用者名和密碼的,是以我需要在Heroku上設定相對應的環境變量,指令如下:

<code>xpleaf@leaf:~</code><code>/Heroku_pro</code><code>$ heroku config:</code><code>set</code> <code>MAIL_USERNAME=</code><code>"xpleaf"</code>

<code>Setting config vars and restarting my-heroku-app-cn... </code><code>done</code>

<code>MAIL_USERNAME: xpleaf</code>

<code>xpleaf@leaf:~</code><code>/Heroku_pro</code><code>$ heroku config:</code><code>set</code> <code>MAIL_PASSWORD=</code><code>"***"</code>

<code>MAIL_PASSWORD: ***</code>

    當然如果你需要設定其它的環境變量,通過這個方式設定就可以了。

8.使用生産Web伺服器

    我們知道,在使用Django或Flask作開發的時候,它們都自帶了開發Web伺服器來連接配接我們的Web應用程式,這對于在開發的過程中來說是再适合不過的了。然而現在我們要做的是在生産環境中部署我們的Web應用程式,是以你不可能說還使用原來這些Web架構自帶的開發伺服器,因為性能實在是不可保證,因為它們都是為開發環境設計的Web伺服器,而不是為生産環境設計的。是以,我們要使用生産環境的Web伺服器。(PS:請注意Web應用程式與Web伺服器的差別)

    我要部署的Web應用程式是基于Flask的,是以當然要使用一個支援Flask的Web伺服器軟體,這裡我使用的是Gunicorn。當然,這取決于你使用的是什麼Web架構,關于這點,可自行去了解。

    選擇了要使用Gunicorn來作為我的生産環境,我待會隻需要把它添加到依賴需求檔案中去就可以了。

    當然,你也完全可以把Gunicorn下載下傳下來進行本地的測試,由于不是每個人都使用的Python Web架構都是Flask或者使用的生Web伺服器軟體是Gunicorn,是以這裡就不提及。

9.添加依賴需求檔案和Profile檔案

    這是必需也是非常重要的一點,否則的話部署很難成功!

    Heroku要求在我們的Web程式(這裡針對Python的Web應用程式)目錄中必須要有下面的兩個檔案:

必需檔案

說明

requirements.txt

Web應用程式所依賴的各種第三方擴充包

Procfile

裡面包含的是我的Web應用伺服器啟動時執行的指令

    正如剛剛在我的Heroku_pro目錄下看到的:

<code>xpleaf@leaf:~</code><code>/Heroku_pro</code><code>$ </code><code>ls</code> <code>-l requirements.txt Procfile </code>

<code>-rw-rw-r-- 1 xpleaf xpleaf 25  1月 29 03:13 Procfile</code>

<code>-rw-rw-r-- 1 xpleaf xpleaf 76  1月 29 03:13 requirements.txt</code>

    注意這兩個檔案必須位于目前Heroku_pro目錄下。

    requirements.txt的檔案内容類似于這樣:

<code>Flask==0.10.1</code>

<code>Flask-Bootstrap==3.0.3.1</code>

<code>Flask-HTTPAuth==2.7.0</code>

<code>Flask-Login==0.3.1</code>

<code>...</code>

<code>SQLAlchemy==0.9.9</code>

<code>WTForms==1.0.5</code>

<code>Werkzeug==0.10.4</code>

<code>alembic==0.6.2</code>

<code>bleach==1.4.0</code>

    裡面包含了支撐我的Web應用程式運作的各種擴充包。當然至于内容是什麼,取決于你正在開發的Web項目。

    而Profile檔案的内容則類似于這樣:

<code>web: gunicorn manage:app</code>

    正如前面所說,裡面放的是指令,比如這裡的這個指令就是用來啟動我前面所說的Gunicorn生産環境Web伺服器的。

    再次說明,這兩個檔案非常重要,如果沒有的話,待會部署就會失敗的。

10.執行git push進行部署

    前面的确認無誤之後,就可以部署了,當然,如果你臨時修改了你目前Heroku_pro目錄下的檔案,請先使用下面的指令送出你的修改:

<code>git add .</code>

<code>git commit -m </code><code>"ver1.0"</code>

    Ok,下面就開始部署:

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

<code>xpleaf@leaf:~</code><code>/Heroku_pro</code><code>$ git push heroku master</code>

<code>對象計數中: 97, 完成.</code>

<code>Delta compression using up to 4 threads.</code>

<code>壓縮對象中: 100% (90</code><code>/90</code><code>), 完成.</code>

<code>寫入對象中: 100% (97</code><code>/97</code><code>), 35.04 KiB | 0 bytes</code><code>/s</code><code>, 完成.</code>

<code>Total 97 (delta 22), reused 0 (delta 0)</code>

<code>remote: Compressing </code><code>source</code> <code>files... </code><code>done</code><code>.</code>

<code>remote: Building </code><code>source</code><code>:</code>

<code>remote: </code>

<code>remote: -----&gt; Python app detected</code>

<code>remote: -----&gt; Installing runtime (python-2.7.11)</code>

<code>remote: -----&gt; Installing dependencies with pip</code>

<code>remote:        Collecting Flask==0.10.1 (from -r requirements</code><code>/common</code><code>.txt (line 1))</code>

<code>..........</code>

<code>remote: -----&gt; Preparing static assets</code>

<code>remote:        Collectstatic configuration error. To debug, run:</code>

<code>remote:        $ heroku run python manage.py collectstatic --noinput</code>

<code>remote: -----&gt; Discovering process types</code>

<code>remote:        Procfile declares types -&gt; web</code>

<code>remote: -----&gt; Compressing...</code>

<code>remote:        Done: 37.2M</code>

<code>remote: -----&gt; Launching...</code>

<code>remote:        Released v6</code>

<code>remote:        https:</code><code>//my-heroku-app-cn</code><code>.herokuapp.com/ deployed to Heroku</code>

<code>remote: Verifying deploy.... </code><code>done</code><code>.</code>

<code>To https:</code><code>//git</code><code>.heroku.com</code><code>/my-heroku-app-cn</code><code>.git</code>

<code> </code><code>* [new branch]      master -&gt; master</code>

    會看到中間有一大堆的輸出資訊,這是Heroku為我們的環境安裝所需的軟體包,而這些軟體包即是前面我們在需求檔案中指定的。當然這些操作都是在Heroku中執行的,我們本地隻是看到它的一個操作過程而已。

    部署完成後,根據我的Flask應用所選擇的Web伺服器的啟動方式,使用下面的指令來進行啟動:

<code>#啟動Web伺服器進行相關初始化配置</code>

<code>xpleaf@leaf:~</code><code>/Heroku_pro</code><code>$ heroku run python manage.py deploy    </code>

<code>Running python manage.py deploy on my-heroku-app-cn... up, run.7690</code>

<code>INFO  [alembic.migration] Context impl SQLiteImpl.</code>

<code>......</code>

<code>INFO  [alembic.migration] Running upgrade 288cd3dc5a8 -&gt; 2356a38169ea, followers</code>

<code>INFO  [alembic.migration] Running upgrade 2356a38169ea -&gt; 51f5ccfba190, comments</code>

<code>#重新啟動</code>

<code>xpleaf@leaf:~</code><code>/Heroku_pro</code><code>$ heroku restart</code>

<code>Restarting dynos... </code><code>done</code>

    上面的完成後,就可以通路我們建立的Web應用了:

    當然,當你通路它的時候可能我已經把它關掉了,你可以通路另一個用同樣方法部署的應用的位址:

11.更新

    如果你需要對你的源代碼修改以增加或删除某些功能,在Heroku_pro目錄下修改了之後,請依次執行下面的指令:

<code>#告訴Heroku,你要進行更新操作</code>

<code>heroku maintenance:on</code>

<code>#送出部署</code>

<code>git push heroku master</code>

<code>#重新運作伺服器</code>

<code>heroku run python manage.py deploy</code>

<code>heroku restart</code>

<code>#告訴Heroku,更新完成</code>

<code>maintenance:off</code>

    Ok,到這裡的話,本文就結束了,其實關于部署應用到Heroku上,無論你的Web應用是基于Python開發的,或者是其它語言,都是類似的,隻是這裡側重說的是Python的Web應用。

    當然在實際的部署過程當中可能會遇到各種各樣的問題,這時就需要充分發揮你的随機應變能力了,當出現問題時,可以Google查找(百度找的資料很少,Google上不了就自己想辦法吧),或者到Stack Overflow上面去查找或是提問,同時要根據提示的錯誤資訊去閱讀官方的文檔來解決存在的問題。

    但不管怎麼說,部署Python Web應用的主要流程是類似于上面所給出的操作,本文相信對初次在Heroku上部署Python Web應用的朋友會有所幫助,寫此文,也确實是希望幫到更多的朋友,因為目前國内有關Python Web部署資源實在不多,更别說部署到國外的雲平台上去了。

本文轉自 xpleaf 51CTO部落格,原文連結:http://blog.51cto.com/xpleaf/1739940,如需轉載請自行聯系原作者