登入  |  English
感謝您對「自由軟體鑄造場」的支持與愛護,十多年來「自由軟體鑄造場」受中央研究院支持,並在資訊科學研究所以及資訊科技創新研究中心執行,現已完成階段性的任務。 原網站預計持續維運至 2021年底,網站內容基本上不會再更動。本網站由 Denny Huang 備份封存。
也紀念我們永遠的朋友 李士傑先生(Shih-Chieh Ilya Li)。
技術專欄 Python/Django on Heroku

Python/Django on Heroku

簡介

自從 Heroku 出現之後,筆者挺羨慕 Rails 的開發者有這麼酷的服務可以使用。不過就在不久前 Heroku 也開始支援 Python 了,便趁著空閒玩了一下。大體而言只要熟悉平常使用的 Python 相關工具,像是 virtualenv、pip 以及 git,整個部署流程就很簡單。

本文將說明如何透過幾個簡單的步驟,把 Django 部署到 Heroku,手腳快的話十分鐘之內便可以看到網站在 Heroku 上運作了。

申請帳號

首先到 Heroku 官方網站註冊並啟用帳號,接下來就可以在本地端操作,而不需至官方網站設定了。因為只要安裝完 Heroku 的 CLI,之後使用 heroku 這個指令即可完成所有的部署流程。

Heroku 的 CLI 有不同平台的 package 供下載安裝,直接到 Heroku Toolbet 即可下載。或者可以直接透過 rubygems 安裝,指令如下:

$ sudo gem install heroku

建立本地端軟體環境

首先要建立並啟用 virtualenv。

$ virtualenv testenv --no-site-packages
$ cd testenv
$ source bin/activate

接下來為了不在 Django 上著墨太多,筆者準備了一份專為部署 Heroku 的 Django 專案,包含了基本的 Django 設定跟部署到 Heroku 的設定檔。筆者把檔案放在 github,可以直接透過此網址下載壓縮檔,解開後把檔案放進剛建立好的 virtualenv,檔案結構如下即可。

注意,別漏了 .gitignore 這個隱藏檔。

Procfile
bin/
herokutest/
include/
lib/
.gitignore
requirements.txt

如果您熟悉 pip 和 virtualenv,就知道接下來必須透過 pip 讀取 requirements.txt 以自動安裝專案所需要的 python packages。

$ pip install -r requirements.txt

接著執行以下指令初始資料庫,然後輸入 Django 所提示的資料即可完成本地資料庫的初始化。

$ python herokutest/manage.py syncdb

然後安裝 foreman,接著用 foreman 運作專案,看看我們的專案是否能夠正常執行。

$ sudo gem install foreman
$ foreman start

最後透過瀏覽器連線到 https://localhost:5000/ 就可以看到執行畫面了。

將程式部署到 Heroku

如果本地端的程式可以正常執行,就可以準備把程式部署到 Heroku 上了。不過這邊得另外說明,由於筆者提供的 Django 設定使用 SQLite3 當作開發用的資料庫,方便本地端開發,但在 Heroku 上必須使用 PostgreSQL,所以部署之前需要先修改 requirements.txt,這樣在部署上 Heroku 時,Heroku 才會幫我們裝上 PostgreSQL 的 driver。

修改方式是於 requirements.txt 檔案上,將最後一行的 psycopg2 的註解拿掉。修改完成如下:

# testenv/requirements.txt
django
gunicorn
psycopg2

取消註解 psycopg2 之後,就可以開始進行第一次 git commit,準備把程式部署到 Heroku。

$ git init
$ git add .
$ git commit -m 'initial commit'

部署前,我們得先使用以下指令登入 Heroku、上傳 ssh 的 public key,並且建立新的 Heroku app。

$ heroku login
$ heroku keys:add
$ heroku create --stack cedar

接下來就可以看到以下訊息,Heroku 已經幫我們建好了 App,並提供 App 的網址,然後 Heroku 會自動把 git remote 加上 Heroku 的位置。

Creating electric-light-4662... done, stack is cedar
https://electric-light-4662.herokuapp.com/ | 
  這個 E-mail 地址已經被防止灌水惡意程式保護,您需要啟用 Java Script 才能觀看
 :electric-light-4662.git

如此就能直接透過 git 把專案送上 Heroku。

$ git push heroku master

在部署的過程中,Heroku 會新增新的資料庫設定到 settings.py 覆蓋原本的設定,以便連到 Heroku 的指定 PostgreSQL。然後會讀取 requirements.txt 安裝所需的 python packages,最後透過 Procfile 執行 web 程式。

最後我們需要初始化 Heroku 上的資料庫,直接透過 heroku run 指令來做遠端執行。

$ heroku run python herokutest/manage.py syncdb

接著輸入 Django 所提示的資料即可完成資料庫的初始化,最後就可以連上 https://.herokuapp.com/admin/app/post/add/ 來登入 Django 的後台新增文章。新增完畢後,回到首頁就看到剛才的資料出現在首頁啦!

碰到的問題

自 Django 1.3 開始,靜態檔是透過 collectstatic 指令收集到同一個目錄,方便透過網頁伺服器處理。所以我們在部署完後,通常會執行以下指令收集靜態檔:

$ heroku run python herokutest/manage.py collectstatic --noinput

然而在透過 heroku run 指令執行 collectstatic 時,Heroku 會開啟另一個 dyno 來執行,所以此時會進入另一個 App 環境,跟我們原先部署的程式空間是分開的,導致無法正確處理靜態檔。

所以筆者用了另一個解法,就是安裝 django-storages 並且將 STATICFILES_STORAGE 設定為 S3Storage,之後執行 collectstatic 指令時,靜態檔就會自動被放上 S3,這麼一來就解決無法把靜態檔放上 Heroku 的問題了。

結語

Heroku 的確大大減輕了部署的很多麻煩,不用自己裝任何伺服器也不需管理,處理 scale 更是輕鬆,只需輸入指令就可以多開一個 dyno 支撐更多流量,讓開發者更能專心在程式開發,不必花時間部署自己的伺服器和後續維護。

在用過好幾家 PaaS 之後,因為各家部署的方式不同,有時會有一些小問題得另外處理,不過單就這次把 twitthat 搬到 Heroku 運作的經驗,除了 staticfiles 的問題之外,Heroku 的部署方式算是設計得挺不錯,而且反應速度也比先前用過的幾個 Python 專屬 PaaS 更快。




自由軟體鑄造場電子報 : 第 188 期 PaaS:程式語言開發在雲端「Programming in Paas」(下)
標籤: PaaS,   platform as a service,   小海,   Python,   Heroku,   Programming on PaaS,   767,  
分類: 技術專欄



評論 

 
0 #1 yeh_ray 2012-01-06 00:22
$ gt add .
$ git commit -am 'initial commit'
-->
git add .
git commit -m 'initial commit'
 
 
0 #2 maggie 2015-07-05 23:49
When I run this comment, there is error back to me and I also try connection the site "django.core.management " that seems not existed any more. Would you please help about it? Thanks!
*************** *****
$ python herokutest/manage.py syncdb
Traceback (most recent call last):
File "herokutest/manage.py", line 2, in
from django.core.management import execute_manager
ImportError: cannot import name execute_manager