終於要git push了

Foreman

Heroku Toolbelt中還包含另一個名爲Foreman的工具,它用於在本地通過Procfile運行程序以進行測試,Heroku客戶端設定的像FLASK_CONFIG這樣的環境變量只能在Heroku服務器上可用,因此要在本地設定,這樣Foreman使用的測試環境才和生產環境類似,Foreman會在程序頂級目錄中搜尋一個名爲.env的文件,加載其中的環境變量,切記這個文件不能添加到Git倉庫中

Foreman有多個命令,其中兩個主要命令是foreman runforeman start,run命令用於在程序的環境中運行任意命令,特別適合運行創建數據庫的deploy命令

(venv) $ foreman run python manage.py deploy

start命令讀取Procfile的內容,執行其中的所有任務,Foreman把所有啓動任務的日誌輸出整合在一起並轉儲到終端,其中每一行的前面都加入了時間戳和任務名

使用-c選項還能模擬多個Dyno,例如啓動3個Web工作線程(Web worker),各職程分別監聽不同端口

(venv) $ foreman start -c web=3

使用Flask-SSLify啓用安全HTTP

用戶登錄程序時要在Web表單中提交用戶名和密碼,這些數據在傳輸過程中可被第三方截取,就像之前多次提及的,爲了避免他人使用這種方式偷取用戶密令,我們必須使用安全HTTP,使用公鑰加密法加密法加密客戶端和服務器之間傳輸的數據

Heroku上的程序在herokuapp.com域中可使用http://和https://訪問,無需任何配置即可使用Heroku的SSL證書,唯一需要做的是讓程序攔截髮往Hhttp://的請求,重定向到https://,這一操作可使用Flask-SSLify擴展完成

我們要將Flask-SSLify擴展添加到requirements.txt文件中,下例爲實現方法,把所有請求重定向到安全HTTP:

# app/__init__.py
def create_app(config_name):
    #...
    if not app.debug and not app.testing and not app.config['SSL_DISABLE']:
        from flask_sslify import SSLify
        sslify = SSLify(app)
    #...

對SSL的支持只需在生產模式中啓用,而且所在平臺必須支持,爲了便於打開和關閉SSL,添加了一個名爲SSL_DISABLE的新配置變量,Config基類將其設爲True,即默認情況下不使用SSL,並且HerokuConfig類覆蓋了這個值,這個變量的配置方式如下:

# config.py
class Config:
    #....
    SSL_DISABLE = True
class HerokuConfig(ProductionConfig):
    #...
    SSL_DISABLE = bool(os.environ.get('SSL_DISABLE'))

在Heroku類中,SSL_DISABLE的值從同名環境變量中讀取,如果這個環境變量的值不是空字符串,那麼將其轉換成布爾值後會得到True,即禁用SSL,如果沒有設定這個環境變量或者其值爲空字符串,轉換成布爾值後會得到False,爲了避免使用Foreman時啓用SSL,必須在.env文件中加入SSL_DISABLE=1

做了以上改動後用戶會強制使用SSL,但還有一個細節需要處理才能完善這一功能,使用Heroku時,客戶端不直接連接託管的程序,而是連接一個反向代理服務器,然後再把請求重定向到程序上,在這種連接方式中,只有代理服務器運行在SSL模式中,程序從代理服務器接收到的請求都沒有使用SSL,因爲在Heroku網絡內部無需使用高安全性的請求,程序生成絕對URL時,要和請求使用的安全連接一致,這時就產生問題了,因爲使用反向代理服務器時,request.is_secure的值一直是False

這個問題會在生成頭像的URL時發生,之前User模型中的gravatar()方法在生成Gravatar URL時檢查了request.is_secure,根據其值的不同分別生成安全或不安全的URL,如果通過SSL請求頁面,生成的卻是不安全的頭像URL,某些瀏覽器會向用戶顯示安全警告,所以同一頁面中的所有內容都要使用安全性相同的URL

代理服務器通過自定義的HTTP首部把客戶端發起的原始請求信息傳給重定向後的Web服務器,所以查看這些首部就有可能知道用戶和程序通信時是否使用了SSL,Werkzeug提供了一個WSGI**中間件**,可用來檢查代理服務器發出的自定義首部並對請求對象進行相應更新,例如修改後的request.is_secure表示客戶端發給反向代理服務器的請求安全性,而不是代理服務器發給程序的請求安全性,下例把ProxyFix中間件添加到程序中:

class HerokuConfig(ProductionConfig):
    #...
    @classmethod
    def init_app(cls, app):
        #...
        # deal with web HEAD
        from werkzeug.contrib.fixers import ProxyFix
        app.wsgi_app = ProxyFix(app.wsgi_app)

ProxyFix中間件添加在Heroku配置的初始化方法中,添加ProxyFix等WSGI中間件的方法是包裝WSGI程序,收到請求時,中間件有機會審查環境,在處理請求之前做些修改,不僅Heroku需要使用ProxyFix中間件,任何使用反向代理的部署環境都需要

執行git push

部署過程的最後一步是把程序上傳到Heroku服務器,在此之前,要確保所有改動都已經提交到本地git倉庫,然後執行git push heroku master把程序上傳到遠程倉庫heroku:

(env) C:\Users\Bangys\Documents\heroku>git push heroku master
Counting objects: 4549, done.
Delta compression using up to 3 threads.
Compressing objects: 100% (4447/4447), done.
Writing objects: 100% (4549/4549), 12.81 MiB | 42.00 KiB/s, done.
Total 4549 (delta 705), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
#...後面就略了

現在程序已經部署好正在運行了,但還不能正常使用,因爲還沒執行deploy命令:

$ heroku run python manage.py deploy

創建並配置好數據庫表之後就可以重啓程序了,直接使用下述命令:

$ heroku restart

查看日誌

程序生成的日誌輸出會被Heroku捕獲,,若想查看日誌內容,可使用heroku logs命令

在測試過程中,還可以使用這個命令方便的跟蹤日誌文件的內容:heroku logs -t

部署一次升級

升級Heroku程序時要重複上述步驟,所有改動都提交到Git倉庫之後,可執行下述命令進行升級

heroku maintenance:on
git push heroku master
heroku run python manage.py deploy
heroku restart
heroku maintenance:off

Heroku客戶端提供i的maintenance命令會在升級過程中下線程序,並向用戶顯示一個靜態頁面,告知網站很快就能修復

發佈了34 篇原創文章 · 獲贊 23 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章