[Python+Django]初心者筆記15(發行應用程式,Deploying Django to production)

[Python+Django]初心者筆記15(發行應用程式,Deploying Django to production)

本文即將使用Heroku來作為發行網站的雲端空間(類似Microsoft 的Azure、GoogleCloud)
在locallibrary\locallibrary\settings.py的設定檔,建議development階段保留一份備份,而production也保留一份備份

首先:註解掉原本的SECRET_KEY,改成由系統環境去重新取得SECRET_KEY

#註解掉原本的SECRET_KEY,改成由系統環境去重新取得SECRET_KEY
# SECURITY WARNING: keep the secret key used in production secret!
# SECRET_KEY = 'n33o*yjq*ca-vm3qf5bx$6tf0_)qs-0r-wy=m5bm284bmp&!&6'
import os
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'cg#p$g+j9tax!#a3cup@1$8obt2_+&k3q+pmu)5%asj6yjpkag')


並且將DEBUG屬性修改成以下:
同樣改成從系統環境的參數設定去取得

# SECURITY WARNING: don't run with debug turned on in production!
# DEBUG = True
DEBUG = bool(os.environ.get('DJANGO_DEBUG', True))


進行下一步之前,必須先到github網站,將程式碼都上傳,因為我們即將使用的雲端空間Heroku,他是透過git來上傳發行的檔案的
請利用github的New Repository功能,並在畫面上填入類似以下的內容(範例):

然後按下畫面上的按鈕clone or download,便可以獲得一個git的網址:
https://github.com/<your_git_user_id>/django_local_library.git


然後透過網頁上提供的編輯功能,改一下.gitignore檔案的內容,加入下面幾行,讓local端的資料不會被push上去:

# Text backup files
*.bak

# Database
*.sqlite3


接著可透過[Git]如何使用SmartGit進行PULL的教學,將這個網址的.gitignore把他pull下來

再來透過[Git]如何透過SmartGit將專案加入本機local端的Git版控的教學,將程式碼commit到本機

再來透過[Git]如何透過SmartGit上傳專案到遠端的教學,將程式碼push到github

接著再於github的根目錄加入一個Procfile檔案(沒有副檔名), 內容為:
意思就是即將在Heroku雲端上面,利用gunicorn這個web server來運作locallibrary網站

web: gunicorn locallibrary.wsgi --log-file -


為了方便設定gunicorn,本機端也要安裝,於終端機執行以下指令安裝gunicorn:

pip install gunicorn


同樣的道理,即將在Heroku上面運行的資料庫,是Heroku postgres雲端資料庫服務的其中一種,叫做hobby-tier,為了方便作後續的設定,請於本機的終端機執行下列指令方便作後續設定:

pip install dj-database-url


接著再次打開/locallibrary/settings.py檔案,在最下面加入以下內容:
這只是要讓測試的時候可以接受最多500個連線,避免每次request都要重新初始化會delay很久,其實沒必要加入(但是我還是加了XD)

# Heroku: Update database configuration from $DATABASE_URL.
import dj_database_url
db_from_env = dj_database_url.config(conn_max_age=500)
DATABASES['default'].update(db_from_env)

接著要處理靜態檔案(例如:圖檔、.js檔案、.css檔)
然後再把下列幾行加入/locallibrary/settings.py檔案的最後面:

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/

# The absolute path to the directory where collectstatic will collect static files for deployment.
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

# The URL to use when referring to static files (where they will be served from)
STATIC_URL = '/static/'

在教學中另外使用了whitenoise這個middleware來加速靜態檔案的存取
whitenoise用來降低web server對於靜態檔案存取的負擔,利用他優秀的壓縮機制壓縮靜態檔案、優秀的cache機制降低直接讀取Server硬碟裡的靜態檔案的機率
請於/locallibrary/settings.py,請將以下內容加入檔案的最後面:
這是用來設定靜態檔案放在Heroku雲端空間的路徑

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/

# The absolute path to the directory where collectstatic will collect static files for deployment.
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

# The URL to use when referring to static files (where they will be served from)
STATIC_URL = '/static/'


為了後續設定方便,請於本機執行下列指令也安裝whitenoise:

pip install whitenoise


然後在於檔案/locallibrary/settings.py加入下面這行,請加在security那行的下面:
讓whitenoise可以順利被加入到認可的middleware

'whitenoise.middleware.WhiteNoiseMiddleware',


Heroku雲端空間的免費方案將會每天將系統環境重新reset,因此需要建立一個requirements.txt
讓他每天reset之後,知道有什麼元件需要重新安裝,請於本機執行下列指令以建立requirements.txt:
requirements.txt所在的位置應該是在locallibrary網站的根目錄

pip freeze > requirements.txt

requirements.txt的內容應該有以下幾項,如果你的安裝元件比下列的還要多,請移除他,避免造成雲端空間的負擔:
如果是相同名稱的元件而只是版本代號不同,那就無傷大雅不用移除
特別要注意的是psycopg2(Python Postgres database support)這項,這項在本機肯定是沒有安裝的,但是Heroku雲端資料庫卻是必要的,Python需透過psycopg2才能在雲端執行SQL,所以請把"psycopg2==2.7.5"這項手動加入到requirements.txt

dj-database-url==0.4.1
Django==2.1
gunicorn==19.9.0
psycopg2==2.7.5
whitenoise==3.2.2

然後需要新增一個runtime.txt,此檔案所在的位置也是在locallibrary網站的根目錄,檔案內容請加入:
這將會提醒Heroku雲端空間記得安裝python runtimes

python-3.6.6

最後在本機再執行一次locallibrary網站,確認剛剛所有的指令沒有影響到原本網站的正常運作:

python manage.py runserver


然後就可以再次將修改過的內容還有新的檔案通通簽入github了!

下一步是去Heroku申請帳號,註冊完畢後,請於此網址https://dashboard.heroku.com/apps選擇python的選項:

然後選擇畫面左方的Setup,根據畫面上的指示安裝Heroku client即可:
安裝Heroku client完畢之後,請於終端機執行下列指令以確認安裝成功:

heroku help

確認安裝成功之後,接著於終端機執行下列指令:
這將會在Heroku雲端空間建立一個網站的web space以及此web space的git空間

heroku create


然後在終端機執行下面指令,讓github的程式碼可以複製一份到Heroku自己的git:
Heroku雲端空間網站的運作,都是用自己的git上面的程式碼在run的

git push heroku master


下一步是讓Heroku雲端空間建立相關的資料庫資料表:

heroku run python manage.py migrate


當然我們也需要建立一些測試用的資料,因此需要superuser的帳號來協助建立,在終端機執行下面的指令以建立superuser的帳號:

heroku run python manage.py createsuperuser


然後在終端機執行以下指令以啟動Heroku雲端空間的網站:
這將會用chrome開啟在Heroku雲端空間的locallibrary網站

heroku open

不過你應該會遇到錯誤訊息的網頁,錯誤訊息將會類似:
Invalid HTTP_HOST header: 'OOXX.herokuapp.com'. You may need to add 'OOXX.herokuapp.com' to ALLOWED_HOSTS
請複製上面的OOXX.herokuapp.com,並且將其加入到/locallibrary/settings.py的ALLOWED_HOSTS變數裡:

ALLOWED_HOSTS = ['<your app URL without the https:// prefix>.herokuapp.com','127.0.0.1']
# For example: 
# ALLOWED_HOSTS = ['fathomless-scrubland-30645.herokuapp.com', '127.0.0.1']

再次commit+push最新的修改到github(自行用終端機指令或是smartgit做commit+push都可以),
並且同時也push最新的修改到Heroku自己的git空間(就是之前的終端機指令:git push heroku master)

再次於終端機執行"heroku open",檢查網站是否運作正常:
沒意外的話應該是正常運作,恭喜你!已完成了local library的tutorial!

補充:
執行下面指令可以瞭解目前Heroku雲端空間安裝了哪些add-on:
可以發現目前安裝的add-on就是postgres雲端資料庫服務而已

heroku addons


要檢查postgresql服務是否還活著、是否正常運作,可以利用以下終端機指令:

heroku addons:open heroku-postgresql


想要檢查設定檔(例如web.config或是app.config之類)的設定的話,可以於終端機執行以下指令:
目前來看,只有一個postgresql資料庫服務的連線字串參數

heroku config


還記得在\locallibrary\settings.py設定的DJANGO_SECRET_KEY以及DJANGO_DEBUG參數嗎?請利用下面終端機指令來複寫這些參數的設定,因為程式碼都放在github上,因此都是open to public無法保密的,因此才需要複寫:
記得下面的DJANGO_SECRET_KEY的值要換成settings.py的被我們註解掉的SECRET_KEY的值喔,設定完畢之後記得把這個被註解掉的值從github上面刪除 XD

heroku config:set DJANGO_SECRET_KEY="eu09(ilk6@4sfdofb=b_2ht@vad*$ehh9-)3u_83+y%(+phh&="


下面指令是用來設定DJANGO_DEBUG,當他是空字串的時候,就代表是False:

heroku config:set DJANGO_DEBUG=


當網站需要進行除錯的時候,可以執行以下指令:

# Show current logs
heroku logs

# Show current logs and keep updating with any new results
heroku logs --tail

# Add additional logging for collectstatic (this tool is run automatically during a build)
heroku config:set DEBUG_COLLECTSTATIC=1

# Display dyno status
heroku ps

或是參考此網址將會有更詳細的log說明:
Django Logging
https://docs.djangoproject.com/en/2.0/topics/logging/


參考資料:
Django Tutorial Part 11: Deploying Django to production
https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Deployment