2017年12月4日教程更新,請移步至最終版本:Django快速部署簡約版 v3.0
以下部分僅作為參考。
2017-05-17網站重寫-博客地址:http://nocmt.com
更換環境為:Python 3.6.1 + Django 1.11.1 + MySQL 5.7.18
一周前試用了一下騰訊云的服務器,默認創建的賬號不是管理員,導致上傳文件失敗,升級權限后卻遠程連接服務器都不行了,而且網速比烏龜的速度都慢,所謂的1m也只是玩笑,所以放棄使用!還是大阿里云好!這次部署的環境依舊是阿里云的Ubuntu 16.04 ,廢話不多說,教程開始!
2018-04-03:發現還是有人收藏本文,所以我就修正一些錯誤,寫的不夠清楚的地方,建議看第三版教程。
1. 環境準備
1.1 更新系統:
sudo apt-get update
sudo apt-get upgrade
提示:安裝時出現的選擇項按自己實際情況選擇。
1.2 安裝SSH:
apt-get install ssh
提示:本人的項目是通過FileZilla Client直接上傳的,其實Pycharm也可以直接上傳項目。
有興趣的可以看看教程:FTP使用教程之Filezilla使用教程
1.3 配置默認的Python環境:
提示:一般默認自帶python2.7+3.5,我們使用的環境是python3.6.1
1.3.1 安裝python-dev包:
apt-get install python-dev
1.3.2 安裝或升級pip :
安裝:
apt-get install python-pip
升級:
pip install --upgrade pip
1.3.3 更換pip源:
提示:因為國內使用默認的pip源速度很慢,所以需要更換,在用戶根目錄下新建 .pip 目錄,在該目錄下新建pip.conf文件。
mkdir ~/.pip
vi ~/.pip/pip.conf
填入:
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com
[list]
format=columns
2. 數據庫安裝
2.1 安裝MySQL:
apt-get install mysql-server
提示:安裝過程中會提示讓你設置MySQL密碼 ,輸入兩次密碼,回車即可,然后等待安裝完成,見下圖。
提示:查看MySQL版本命令:
mysql --version
2.2 運行數據庫Mysql安全配置向導:
mysql_secure_installation
選擇說明:
- Enter password for user root:輸入root用戶密碼并回車。
- VALIDATE PASSWORD......Press y|Y for Yes, any other key for No:是否設置驗證密碼,直接回車選擇不。
- Change the password for root? :是否更改root用戶的密碼?由于之前設置過,所以這里不更改,直接回車選擇不。
- Remove anonymous users?:是否刪除匿名用戶?輸入y并回車。
- Disallow root login remotely?: 是否禁止root登錄遠程?輸入y并回車。
- Remove test database and access to it?: 刪除測試數據庫并訪問它?輸入y并回車。
- Reload privilege tables now?:現在重新加載權限表?輸入y并回車。
如果出現這種錯誤:
[error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)']
它表明你的Mysql服務,并沒有開啟!輸入下列命令開啟即可:
service mysql start
sudo表明以管理員權限執行:如何啟動/停止/重啟MySQL
2.3 配置Mysql默認字符集
提示:此時當前目錄為根目錄,進入 /etc/mysql/,打開 my.cnf。
不太熟悉vi命令的同學看這里:linux下vi命令大全
cd /etc/mysql/
vi my.cnf
按一下 i 代表輸入操作,填入以下代碼(如果數據庫版本不是5.7.11+,里面的配置可能很亂,那就不要動它了。):
[client]
port = 3306
socket = /var/lib/mysql/mysql.sock
default-character-set=utf8
[mysqld]
port = 3306
socket = /var/lib/mysql/mysql.sock
character-set-server=utf8
[mysql]
no-auto-rehash
default-character-set=utf8
提示:編輯完成后按一下鍵盤 ESC 輸入:wq,代表保存退出,然后重啟mysql服務使其生效:
service mysql restart
2.4 創建網站的數據庫:
提示:進入mysql shell:
mysql -uroot -p
提示:接下來創建數據庫并指定編碼方式為UTF-8(其中dataname 為數據庫名稱,保證與Django連接數據庫名稱一致,否則連接會出錯):
CREATE DATABASE `dataname` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
提示:數據庫操作基本命令:
SHOW DATABASES; #顯示所有數據庫
USE <NAME>; #進入某數據庫
SHOW TABLES; #顯示所有數據表
SELECT * FROM <NAME>; #查詢表內容
多余的不說了,忘記的看看:mysql基本操作命令匯總
退出命令:quit 退回根目錄 :cd
3. 關于Django項目靜態文件的說明:
一般在開發環境中: 即settings.py中的DEBUG = True 時 , Django 會自動幫助我們處理靜態文件,所以不用操心靜態文件不加載的問題,但是在部署時,出于安全考慮,我們必須關閉DEBUG!保證自己網站的信息不泄露。只是當DEBUG關閉后,Djang就不會幫我們處理靜態文件了,所以會出現樣式丟失,靜態文件404問題。
3.1 文件說明:
- MEDIA_ROOT:媒體文件收集路徑,所有上傳的文件存儲路徑。示例:圖像,文件。
- STATIC_ROOT:靜態文件收集路徑, 在開發中,STATIC_ROOT什么都不做。你甚至不需要設置它。
- STATICFILES_DIRS :靜態文件的額外目錄,STATICFILES_DIRS用于包含要查找的其他靜態文件目錄。比如你自己新建的一個靜態文件文件夾。
說明:Django在每個應用程序目錄(項目/Apps/static)中自動查找靜態文件。當你的項目部署時,事情有所不同,Django處理靜態文件能力并不強,于是在實際生產環境時它將這個任務交給了Nginx。
而為什么要收集到一個文件夾內呢?這是因為如果你項目存在很多APP,每個APP下又有不同的靜態文件,Nginx可不會自動尋找,它的配置文件中只能指定一個靜態文件路徑,于是有了這個命令:python manage.py collectstatic,后面你會了解它的用法。
3.2 部署前Django項目settings.py中的設置:
提醒:首先DEBUG設置為False,ALLOWED_HOSTS里面填入你的域名或者IP。
DEBUG = False
ALLOWED_HOSTS = ['nocmt.com', 'www.nocmt.com']
提醒:時區+語言+收集靜態文件目錄設置
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',)
4. 安裝Python 3.6.1
4.1 教程:
點擊這個:Ubtuntu16.04 安裝 python3.6.1 教程
提示:如果下載速度太慢,就看上面的 FileZilla 教程,自己下載好壓縮包上傳上去,再解壓安裝。CTRL+Z退出。
4.2 安裝虛擬環境,我們在這里淘汰virtualenv。
提示:因Python3+自帶虛擬環境,更簡單好用,所以沒必要再裝一個。
在home目錄下創建名稱為vcmt的虛擬環境。
python3.6 -m venv /home/vcmt
激活虛擬環境:
source /home/vcmt/bin/activate
記住退出命令為:deactivate
4.3 快速安裝原開發環境中的所有第三方庫:
提示:首先在開發機上中的控制臺輸入(當然是你項目依賴的python環境下):
pip freeze > requirements.txt
這會在當前目錄生成一個第三方庫列表。
把生成的requirements.txt文件復制到服務器上,隨便一個目錄都可以。
在服務器上執行:
pip install -r requirements.txt
它會自動讀取requirements.txt中的擴展庫信息并在本機進行安裝。
這里我們利用 FileZilla Client把文件上傳上去,并且把Django項目丟上去。
我的目錄一般在/home/下。
注意:上傳項目文件后把 /項目名/app名/migrations/ 下的類似00.. 的記錄文件刪除,有幾個刪除幾個,但是不要刪除別的文件。
這是在本地進行數據同步時產生的記錄文件,由于我們并不是轉移的數據庫,所以要刪除舊的記錄!
5. Django數據庫配置+靜態文件收集+管理員建立
5.1 進入Django項目下,同步并創建數據庫,執行:
cd /home/suly/
python manage.py makemigrations
python manage.py migrate
注意:如果出錯了,首先檢查models.py 里面是不是有什么錯誤,包括在第一行設置UTF-8編碼方式,因為我發現它有時也會出現這種問題!再檢查settings.py 關于連接部分的設置對不對,最后檢查是不是3306端口沒打開!一般都是這幾個問題。
5.2 建立后臺超級用戶:
python manage.py createsuperuser
啟動自帶的服務器,測試是否可以正常運行!(此時settings.py 中的DEBUG = False)輸入:
python manage.py runserver 0.0.0.0:8000
提醒:如果無法訪問,是因為默認8000端口關閉了,打開它是在阿里云配置安全組里面,自己去找找。
而打開端口后出現:Bad Request (400),是因為我們之前ALLOWED_HOSTS里面只添加了域名,不過如果按照教程一步一步來的,沒有必要測試,我這邊啟動時也沒報錯,所以判斷是完美的。不管它,CTRL+Z 強制退出!并清理8000端口相關聯的進程。
fuser -k 8000/tcp
5.3 同步靜態文件:
python manage.py collectstatic
此時項目下的settings.py 中的STATIC_ROOT 后面的文件夾應該是'static' .
6. uWSGI的安裝
6.1 安裝:
pip install uwsgi
正常啟動測試(suly為項目名稱):
uwsgi --http :8000 --chdir /home/suly/ -w suly.wsgi
提醒:訪問地址為(http://ip:8000)同時確保你的8000端口已經開啟。
注意:這里有些朋友訪問測試時會出現502錯誤,這個時候控制臺會詳細輸出日志,按照上面的提示修改代碼。
如果修改好以后啟動沒有問題,但還是訪問不了,那么你需要將Django的settings.py 里面的DEBUG=True,ALLOW_HOST=['*'],保存重新開啟并調試!大部分人會卡在這個步驟,如果確認你的代碼沒有問題,你就不要管這里了,直接往下部署,把所有文件全部弄好后,再來調試!后面我有時間也可以遠程幫你!
記住部署完成后你需要恢復原來的樣子!
6.2 uWSGI的配置:
首先建立一個配置目錄及文件:
mkdir -p /etc/uwsgi/sites
cd /etc/uwsgi/sites
在里面建立以自己項目名命名的配置文件:
vi suly.ini
填入以下內容:你只需要改project和Base,一個項目名稱,一個項目路徑。
[uwsgi]
project = suly
base = /home
chdir = %(base)/%(project)
module = %(project).wsgi:application
master = true
processes = 5
socket = %(base)/%(project)/%(project).sock
chmod-socket = 666
vacuum = true
現在建立一個自啟腳本:
vi /etc/init/uwsgi.conf
內容如下 setuid的值改為你的項目名:
description "uWSGI application server in Emperor mode"
start on runlevel [2345]
stop on runlevel [!2345]
setuid suly
setgid www-data
exec /usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
最后一個問題,www-data 用戶組沒有創建。
7. Nginx的安裝和配置
7.1 安裝
apt-get install nginx
7.2 創建配置文件
vi /etc/nginx/sites-available/suly
提示:填寫內容如下(server_name為被解析域名,如果暫時沒有域名那就填公網IP,Django項目settings.py中的,靜態文件夾地址一定要填對,否則樣式會出錯!):
基礎版:
server {
listen 80;
server_name nocmt.com;
location /static/ {
root /home/suly;
}
location /media/ {
root /home/suly;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/home/suly/suly.sock;
}
}
日志版:
server {
listen 80;
server_name nocmt.com;
access_log /home/suly/nginx.access.log;
error_log /home/suly/nginx.error.log;
location / {
include uwsgi_params;
uwsgi_pass unix:/home/suly/suly.sock;
}
location /static/ {
root /home/suly;
}
location /media/ {
root /home/suly;
}
location /favico.ico {
root /home/suly/static/img/favico.ico;
}
}
保存退出!
多站點多域名看這里:Nginx多站點+301重定向的配置
然后鏈接文件:
ln -s /etc/nginx/sites-available/suly /etc/nginx/sites-enabled/
檢查是否有錯誤的命令:
service nginx configtest
提示:出現錯誤,那就是配置文件寫錯了,自己檢查一下,沒有就直接啟動!
關于檢查錯誤,需要查看Nginx的錯誤日志,/etc/nginx/nginx.conf文件內最下面會有路徑代碼。
這里不做過多闡述。后續更新教程再說。
重啟命令:
service nginx restart
啟動uwsgi :
uwsgi /etc/uwsgi/sites/suly.ini -d /home/suly/suly.log
訪問你的網站,試試看!如果有問題可以評論或者簡信我!
以下的錯誤,是因為我之前安裝uwsgi時是使用的sudo方式,導致安裝到Python2.7上面去了,后面我已經全部修正錯誤了,這種情況就沒有再出現過。
我在后臺提交數據時總是出現500錯誤,于是我把Debug開啟,得到的錯誤消息如下:
我怎么解決的:
思路:我們都知道python2.7默認編碼方式是ascil,而中文是需要utf-8支持的,于是我們只要修改python默認的字符編碼為utf-8就可以了,經過查詢,我得到ubuntu的python2.7安裝目錄 為:/usr/lib/python2.7,在它的目錄下打開一個叫sitecustomize.py的文件,如果沒有就建立一個,它的作用就是在python啟動時就會執行一次該腳本。我們在最前面寫入下面幾行代碼(里面會有幾行代碼,不要管它):
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
測試,命令行輸入python2.7,啟動shell,輸入:
import sys
sys.getdefaultencoding()
返回'utf-8'!退出shell重啟uwsgi,沒問題了。
參考文章:
3.在 Ubuntu 16.04 LTS 上安裝 Python 3.6.0
4.Linux下MySQL 5.5/5.6的修改字符集編碼為UTF8
5.STATICFILES_DIR,STATIC_ROOT和MEDIA_ROOT之間的差異
6.Ubuntu+Django+Nginx+uWSGI+Mysql搭建Python Web服務器
7.五步教你實現使用Nginx+uWSGI+Django方法部署Django程序(上)
8.五步教你實現使用Nginx+uWSGI+Django方法部署Django程序(下)
9.Django + uwsgi + nginx + bootstrap 創建自己的博客 -- 13.部署
10.CentOS+Apache+mod_wsgi+Python+Django - 昨、夜星辰 - 博客園
......