Django 博客開發教程 14 - 使用 Nginx 和 Gunicorn 部署 Django 博客
我們博客的基礎功能已經開發的基本差不多了,雖然還有很多地方可以完善,但我們還是希望早點把博客部署到服務器上,讓他人可以通過外網訪問。至於有待完善的地方,可以等部署完後一點點地迭代和改進。現在就讓我們來把博客部署到服務器上吧!
注意:本文的每一個步驟都在真實環境下驗證無誤。除非你知道自己在做什麼,否則我們建議每一步均嚴格按照教程的指導來,這樣能保證你順利完成部署。
部署前準備
我們將使用比較流行的 Nginx + Gunicorn 的方式將 Django 開發的博客部署到自己的服務器,讓別人能夠通過域名訪問你的博客。至於 Nginx、Gunicorn 是什麼暫時放到一邊,讀完本教程後你就會知道它們的作用和使用方法了。
為了部署我們的博客,需要滿足以下兩個條件:
- 有一台可以通過外網訪問的服務器。
- 有一個域名。
如果你已經滿足以上條件,可以直接跳到後麵的搭建服務器部分。這裏簡單介紹一下我目前所知的以最低成本滿足以上兩個條件的方式。
購買服務器
如果你是學生,推薦購買阿裏雲服務器,學生優惠價是 9.9 元/月,而且服務器性能比較高。購買地址:阿裏雲服務器學生專區。具體的購買步驟這裏就不贅述了,根據網站的指引相信你肯定能夠購買成功。隻是注意一點的是在選服務器類型的時候選擇**公共鏡像**,這樣係統比較純淨。操作係統建議選 ubuntu 14.04 64位,這是本教程使用的服務器環境。
如果你不是學生,推薦購買搬瓦工 vps。目前最便宜的是 19.9美元/年,缺點是服務器性能沒有阿裏雲高,但優點是順帶可以用它來搭梯子,從此訪問 google、youtube 不是夢(基於 shadowsocks 隻需簡單幾步就可以搭建起自己的梯子服務器)。同樣購買的過程就不贅述了,搬瓦工 vps 中文網 有超級詳細的指引。隻是注意安裝操作係統時建議選 ubuntu 14.04 64位,這是本教程使用的服務器環境。
如果你不差那點錢,隨意選擇一個雲服務器提供商購買一個雲服務器即可。
購買域名
域名服務商很多,我這裏使用的是 阿裏雲域名注冊係統。域名是網站的門牌,如果打算長期運營這個網站建議多考慮考慮,選一個適當的域名。如果隻是為了測試,隨便注冊一個域名即可,一些非常見後綴的域名非常便宜,一般 10元/年就能搞定。但注意一點根據工信部規定,以下後綴的域名需要實名認證後才能使用:
.cn/.com/.net/.top/.xyz/.vip/.club/.ren/.wang/.shop/.xin/.中國/.信息/.公司/.網絡/.廣東/.佛山
如果你購買的是上述後綴的域名,意味著需要提交個人的身份資料實名認證後才能正常使用,這通常需要花費幾天的時間。所以如果隻為了測試和學習部署的話,最好避開上述後綴的域名。
搭建服務器
本教程使用的本地環境為 Windows 10,服務器環境為 ubuntu 14.04(64 位)。**如果你的環境和我的有所差異導致一些命令無法執行,將這些命令轉換為你所在環境的命令執行即可。**
### 遠程登錄到服務器
服務器通常位於雲端,需要使用遠程登錄工具登錄後才能對服務器進行操作。我使用的是 Xshell,Windows 下百度 Xshell 下載安裝即可,軟件對學校和個人用戶是免費的。
如何遠程登錄到服務器這裏就不贅述了,相信你參考網上的一些教程肯定能夠順利登錄。假如你和我一樣使用 Xshell 的話,這裏有一篇很詳細的教程可以參考:教你怎麼使用xshell遠程連接linux服務器。
安裝軟件
順利連接到遠程服務器了。如果是一台全新服務器的話,通常我們是以 root 用戶登錄的。在 root 下部署代碼不安全,最好是建一個新用戶(如果你已經以非 root 用戶登錄的話可以跳過這一步)。下麵的一些列命令將創建一個擁有超級權限的新用戶:
# 在 root 用戶下運行這條命令創建一個新用戶,yangxg 是用戶名
# 因為我叫楊學光,所以我取的用戶名是 yangxg
# 選擇一個你喜歡的用戶名,不一定非得和我的相同
root@localhost:~# useradd -m -s /bin/bash yangxg
# 把新創建的用戶加入超級權限組
root@localhost:~# usermod -a -G sudo yangxg
# 為新用戶設置密碼
# 注意在輸密碼的時候不會有字符顯示,不要以為鍵盤壞了,正常輸入即可
root@localhost:~# passwd yangxg
# 切換到創建的新用戶
root@localhost:~# su - yangxg
# 切換成功,@符號前麵已經是新用戶名而不是 root 了
yangxg@localhost:~$
新用戶創建並切換成功了。如果是新服務器的話,最好先更新一下係統,避免因為版本太舊而給後麵安裝軟件帶來麻煩。運行下麵的兩條命令:
yangxg@localhost:~$ sudo apt-get update
yangxg@localhost:~$ sudo apt-get upgrade
接下來就可以安裝必要的軟件了,這裏我們需要用到的軟件有 Nginx、Pytohn3、Git、pip 和 virtualenv。
yangxg@localhost:~$ sudo apt-get install nginx
yangxg@localhost:~$ sudo apt-get install git python3 python3-pip
yangxg@localhost:~$ sudo pip3 install virtualenv
解析域名到服務器的 IP 地址
將域名和服務器的 IP 地址綁定後,用戶就可以通過在瀏覽器輸入域名來訪問服務器了。
各大域名服務商都提供了域名解析服務,但其配置界麵各有差異,請依據其指引完成域名解析。下麵是我使用的阿裏雲域名解析頁麵。
啟動 Nginx 服務
Nginx 是用來處理靜態文件請求的。比如當我們訪問一個博客文章詳情頁麵時,服務器會接收到下麵兩種請求:
- 顯示文章的詳情信息,這些信息通常保存在數據庫裏,因此需要調用數據庫獲取數據。
- 圖片、css、js 等存在服務器某個文件夾下的靜態文件。
對於前一種請求,博客文章的數據需要借助 Django 從數據庫中獲取,Nginx 處理不了,它就會把這個請求轉發給 Django,讓 Django 去處理。而對於後一種靜態文件的請求,隻需要去這些靜態文件所在的文件夾獲取,Nginx 就會代為處理,不再麻煩 Django。
用 Django 去獲取靜態文件是很耗時的,但 Nginx 可以很高效地處理,這就是我們要使用 Nginx 的原因(當然其功能遠不止這些)。
通過前麵的步驟我們已經安裝了 Nginx,並且已經把域名和服務器 IP 綁定了。運行下麵的命令啟動 Nginx 服務:
yangxg@localhost:~$ sudo service nginx start
在瀏覽器輸入域名,看到如下頁麵說明 Nginx 啟動成功了。
部署代碼
部署前的項目配置
Django 項目中會有一些 CSS、JavaScript 等靜態文件,為了能夠方便地讓 Nginx 處理這些靜態文件的請求,我們把項目中的全部靜態文件收集到一個統一的目錄下,這個目錄通常位於 Django 項目的根目錄,並且命名為 static。為了完成這些任務,需要在項目的配置文件裏做一些必要的配置:
blogproject/settings.py
# 其他配置...
STATIC_URL = '/static/'
# 加入下麵的配置
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_ROOT 指明了靜態文件的收集目錄,即項目根目錄(BASE_DIR)下的 static 文件夾。
為了安全起見,在生產環境下需要關閉 DEBUG
選項以及設置允許訪問的域名。打開 settings.py 文件,找到 DEBUG
和 ALLOWED_HOSTS
這兩個選項,將它們設置成如下的值:
blogproject/settings.py
DEBUG = False
ALLOWED_HOSTS = ['127.0.0.1', 'localhost ', '.zmrenwu.com']
ALLOWED_HOSTS
是允許訪問的域名列表,127.0.0.1 和 localhost 是本地訪問的域名,.zmrenwu.com 是訪問服務器的域名(**換成你自己的域名**)。域名前加一個點表示允許訪問該域名下的子域名,比如 www.zmrenwu.com、test.zmrenwu.com 等二級域名同樣允許訪問。如果不加前麵的點則隻允許訪問 zmrenwu.com。
項目還會依賴一些第三方 Python 庫,為了方便在服務器上一次性安裝,我們將全部依賴寫入一個叫 requirements.txt 的文本文件中。激活**本地**的虛擬環境(如果你使用了虛擬環境的話),並進入項目的根目錄,運行 pip freeze > requirements.txt
命令:
(blogproject_env) C:\Users\yangxg\Workspace\blogproject>
pip freeze > requirements.txt
這時項目根目錄下會生成了一個 requirements.txt 的文本文件,其內容記錄了項目的全部依賴。
將代碼上傳到 GitHub
將代碼上傳到 GitHub 等代碼托管平台,這樣我們就可以方便地把代碼拉取到服務器了。Git 和 GitHub 的使用相信你已經很熟悉了,這裏就不贅述過程。如果不知道如何使用地話可以自行百度相關教程。
注意數據庫文件不要上傳!
設置服務器目錄結構
接下來需要把代碼上傳到服務器了。我服務器上存放代碼的目錄結構一般是這樣的:
/home/yangxg/
sites/
demo.zmrenwu.com/
env/
django-blog-tutorial/
一台服務器可能部署多個網站,所有網站代碼都放在 sites/ 目錄下。demo.zmrenwu.com/ 這個文件夾以網站的域名命名,便於區分。env/ 是 python 虛擬環境目錄。django-blog-tutorial/ 是 Django 博客項目目錄。
因此先來創建這個目錄結構,**注意目錄名替換為你自己的域名,以後涉及到 demo.zmrenwu.com 的地方通常都要替換你自己的域名,後麵就不再一一指出了**,運行下麵的命令,
yangxg@localhost:~$ mkdir -p ~/sites/demo.zmrenwu.com
這裏 ~ 代表當前用戶的 home 目錄,即 /home/yangxg/。
接下來創建虛擬環境,先進入到 demo.zmrenwu.com 目錄下,然後運行 virtualenv 命令創建虛擬環境:
yangxg@localhost:~$ cd ~/sites/demo.zmrenwu.com
yangxg@localhost:~/sites/demo.zmrenwu.com$ virtualenv --python=python3 env
注意這裏使用 --python=python3 來指定克隆 Python3 的環境。因為 ubuntu 係統默認安裝了 Python2,如果不特別指定的話 Virtualenv 默認克隆的是 Python2 的環境。
檢查一下虛擬環境是否創建成功,運行 ls 命令列出當前目錄下的文件和文件夾,看到 env 這個文件夾說明虛擬環境創建成功。
yangxg@localhost:~/sites/demo.zmrenwu.com$ ls
env
接著再從代碼倉庫把項目代碼拉取過來,**把 git clone 後的地址換成你自己的 GitHub 倉庫地址!**
yangxg@localhost:~/sites/demo.zmrenwu.com$ git clone https://github.com/zmrenwu/django-blog-tutorial.git
運行 ls 命令檢查一下是否拉取成功:
yangxg@localhost:~/sites/demo.zmrenwu.com$ ls
django-blog-tutorial env
多了 django-blog-tutorial 文件夾(文件夾名稱由你的 GitHub 倉庫名決定),說明拉取成功了。
安裝項目依賴
激活虛擬環境,再進入到項目根目錄,即 requirements.txt 所在的目錄,安裝項目的全部依賴:
yangxg@localhost:~/sites/demo.zmrenwu.com$ source env/bin/activate
(env) yangxg@localhost:~/sites/demo.zmrenwu.com$ cd django-blog-tutorial/
(env) yangxg@localhost:~/sites/demo.zmrenwu.com/django-blog-tutorial$ pip install -r requirements.txt
收集靜態文件
虛擬環境下繼續運行 python manage.py collectstatic
命令收集靜態文件到 static 目錄下:
(env) yangxg@localhost:~/sites/demo.zmrenwu.com/django-blog-tutorial$ python manage.py collectstatic
生成數據庫
虛擬環境下繼續運行 python manage.py migrate
命令創建數據庫文件:
(env) yangxg@localhost:~/sites/demo.zmrenwu.com/django-blog-tutorial$ python manage.py migrate
創建超級用戶
虛擬環境下繼續運行 python manage.py createsuperuser
命令創建一個超級用戶,方便我們進入 Django 管理後台。這和本地開發時是一樣的,具體請參照:在 Django Admin 後台文章。
(env) yangxg@localhost:~/sites/demo.zmrenwu.com/django-blog-tutorial$ python manage.py createsuperuser
配置 Nginx
接下是配置 Nginx 來處理用戶請求。
先在服務器的 /etc/nginx/sites-available/ 目錄下新建一個配置文件,文件名我一般就設置為域名。寫上下麵的配置內容:
/etc/nginx/sites-available/demo.zmrenwu.com
server {
charset utf-8;
listen 80;
server_name demo.zmrenwu.com; ①
location /static { ②
alias /home/yangxg/sites/demo.zmrenwu.com/django-blog-tutorial/static;
}
location / { ③
proxy_set_header Host $host;
proxy_pass https://unix:/tmp/demo.zmrenwu.com.socket;
}
}
① 服務的域名為 demo.zmrenwu.com。
② 所有URL 帶有 /static 的請求均由 Nginx 處理,alias 指明了靜態文件的存放目錄。
③ 其它請求轉發給 Django 處理。proxy_pass 後麵使用了 unix 套接字,其作用是防止端口衝突,這裏就不再詳述。
至於怎麼在服務器新建文件和寫文件,請自行學習一點點 vi 編輯器的用法,這裏也不一一講解了。
我們在 /etc/nginx/sites-available/ 放置了配置文件,接下來需要創建一個符號鏈接,把這個配置文件加入到啟用的網站列表中去,被啟用網站的目錄在 /etc/nginx/sites-enabled/,你可以理解為從 sites-available/ 目錄下發送了一個配置文件的快捷方式到 sites-enabled/ 目錄。具體命令如下:
(env) yangxg@localhost:~/sites/demo.zmrenwu.com/django-blog-tutorial$ sudo ln -s /etc/nginx/sites-available/demo.zmrenwu.com /etc/nginx/sites-enabled/demo.zmrenwu.com
使用 Gunicorn
Gunicorn 一般用來管理多個進程,有進程掛了Gunicorn 可以把它拉起來,防止服務器長時間停止服務,還可以動態調整 worker 的數量,請求多的時候增加 worker 的數量,請求少的時候減少。
在虛擬環境下,安裝 Gunicorn:
(env) yangxg@localhost:~/sites/demo.zmrenwu.com/django-blog-tutorial$ pip install gunicorn
用 Gunicorn 啟動服務器進程:
(env) yangxg@localhost:~/sites/demo.zmrenwu.com/django-blog-tutorial$ gunicorn --bind unix:/tmp/demo.zmrenwu.com.socket blogproject.wsgi:application
瀏覽器輸入域名,可以看到訪問成功了!
自動啟動 Gunicorn
現在 Gunicorn 是我們手工啟動的,萬一哪天服務器崩潰重啟了又得重新手工啟動。為此我們寫一個自動啟動腳本,這樣當服務器重新啟動後,腳本會幫我們重啟 Gunicorn。先按 Ctrl + c 停止剛才啟動的服務器進程。
寫一個啟動腳本,這樣當服務器重啟後能自動引導 Gunicorn 的啟動。腳本位於 /etc/init/ 目錄下,且腳本文件名必須以 .conf 結尾:
/etc/init/gunicorn-demo.zmrenwu.com.conf
start on net-device-up ①
stop on shutdown
respawn ②
setuid yangxg ③
chdir /home/yangxg/sites/demo.zmrenwu.com/django-blog-tutorial ④
exec ../env/bin/gunicorn --bind unix:/tmp/demo.zmrenwu.com.socket blogproject.wsgi:application ⑤
① start on net-device-up 確保隻在服務器聯網時才啟動 Gunicorn。
② 如果進程崩潰了(比如服務器重啟或者進程因為某些以外情況被 kill),respawn 將自動重啟 Gunicorn。
③ setuid 確保以 yangxg 用戶的身份(換成你自己的用戶名)運行 Gunicorn 進程。
④ chdir 進入到指定目錄,這裏進入項目的根目錄。
⑤ exec 執行進程,即開啟服務器進程。
現在可以用 start 命令啟動 Gunicorn 了:
sudo start gunicorn-demo.zmrenwu.com
以後如果更新了代碼,隻要運行下麵的命令重啟一下 Nginx 和 Gunicorn 就可以使新的代碼生效了:
sudo service nginx reload
sudo restart gunicorn-demo.zmrenwu.com
使用 CDN 加快 Bootstrap 和 jQuery 的加載速度
我們的項目使用了 Bootstrap 和 jQuery,這兩個文件我們是從本地加載的。如果服務器性能比較差的話,加載需要耗費很長的時間,網站打開的速度就變得無法忍受。我們使用 CDN 來加快加載速度。具體來說,替換 base.html 的幾個靜態文件的加載標簽:
base.html
- <link rel="stylesheet" href="{% static 'blog/css/bootstrap.min.css' %}">
- <script src="{% static 'blog/js/jquery-2.1.3.min.js' %}"></script>
- <script src="{% static 'blog/js/bootstrap.min.js' %}"></script>
+ <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
+ <script src="https://cdn.bootcss.com/jquery/2.1.3/jquery.min.js"></script>
+ <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
這樣網站訪問的速度將大大提升!
部署過程自動化
在整個部署過程中我們運行了十幾條命令,手動輸入了 N 個字符。如果每次更新代碼都要遠程連接到服務器執行這些命令的話將變得非常麻煩。接下來的教程我們將介紹使用 Fabric 自動化整個部署過程。寫好部署腳本後,隻需要執行一條命令,就可以非常方便地自動完成整個部署。
總結
本章節的代碼位於:Step14: deploy using nginx and gunicorn。
如果遇到問題,請通過下麵的方式尋求幫助。
- 在 使用 Nginx 和 Gunicorn 部署 Django 博客- 追夢人物的博客 的評論區留言。
- 將問題的詳細描述通過郵件發送到 djangostudyteam@163.com,一般會在 24 小時內回複。
更多Django 教程,請訪問 追夢人物的博客 和 Python 中文社區。
最後更新:2017-06-01 21:02:20