現有的腳本、工具想找個統一的地方能讓開發和其他人員使用,就想弄個網站。調研了下,發現Django不錯,雖然都說性能不好,但上手快、敏捷開發,符合我們內部使用需求,就用他了。下面記錄我搭建Django服務的過程
一、申請服務器(阿里云、騰訊云等等,略)
注:下面的命令是在linux下的,如果是CentOS的,把相應命令改成yum的命令即可
二、安裝和開d發環境一致的python版本
1、安裝python3.6
apt-get install software-properties-common
add-apt-repository ppa:jonathonf/python-3.6
apt-get update
apt-get install python3.6
2、創建軟連接
cd /usr/bin
# 如果還需要保留python2的,則下面刪除python的軟連接不用操作
rm python
ln -s python3.6 python
rm python3
ln -s python3.6 python3
3、安裝pip
apt-get install python3-pip
pip3 install --upgrade pip
如果是CentOS系統,可以參考這篇文章
4、安裝虛擬環境(可選)
pip3 install virtualenv
5、創建虛擬環境(可選)
virtualenv mysite_env #創建虛擬環境
source mysite_env/bin/activate # 進入虛擬環境
deactivate #退出虛擬環境
若出現找不到virtualenv命令提示,可參考這篇文章
三、安裝Git(或其他的代碼管理工具)
# 安裝Git
apt-get install git
# clone項目代碼
git clone XXX項目地址
CentOS系統下編譯安裝(yum安裝的版本過低)可參考這篇文章
四、安裝項目依賴包
1、生成、安裝依賴包
# 在開發環境生成requirements.txt文件
pip freeze >requirements.txt
# 由于默認的pip freeze命令生成的依賴包是你環境下所有的包,不是跟你項目相關的包也會生成,可能會有很多,所以這里我使用第三方包 pipreqs
pipreqs ./
# pipreqs 會去遍歷你項目目錄,盡可能的識別你的依賴包,但可能會遺漏,需要你檢查下
# 在服務器上安裝依賴文件
pip install -r requirements.txt
2、安裝依賴包時報錯的解決
-
問題1:安裝mysqlclient出現“OSError: mysql_config not found”錯誤
解決方法:
apt-get install libmysqlclient-dev python3-dev
# CenOS系統下的命令
yum install mysql-devel gcc gcc-devel python-devel
-
問題2:matplotlib安裝報錯
解決方法見這篇文章
-
問題3: 提示xadmin-2.0.1找不到,這是因為xadmin針對Django2版本的包是手動安裝的(增強的后臺管理插件,不需要的可不裝)
解決方法:
# 手動安裝
pip install git+git://github.com/sshwsfc/xadmin.git@django2
五、安裝配置mysql數據庫
1、安裝mysql
wget https://dev.mysql.com/get/mysql-apt-config_0.8.10-1_all.deb
dpkg -i mysql-apt-config_0.8.10-1_all.deb
apt-get update
apt-get install mysql-server
# 然后設置密碼
CentOS系統下安裝mysql可參考這篇文件(mysql5.6)
2、配置數據庫(配置文件一般在/etc/my.cnf 文件里)
[mysqld]
# 設置默認使用的端口
port=3306
# 允許最大連接數
max_connections=200
# 允許連接失敗的次數。這是為了防止有人試圖攻擊數據庫
max_connect_errors=10
# 服務端使用的字符集
character-set-server=utf8mb4
# 數據庫字符集對應一些排序等規則使用的字符集
collation-server=utf8mb4_general_ci
# 創建新表時將使用的默認存儲引擎
default-storage-engine=INNODB
# 默認使用“mysql_native_password”插件作為認證加密方式
# MySQL8.0默認認證加密方式為caching_sha2_password
default_authentication_plugin=mysql_native_password
3、創建用戶、創建庫
#進入數據庫
mysql -u root -p
# 創建庫
CREATE DATABASE mysite_db DEFAULT CHARSET=utf8 DEFAULT COLLATE utf8_unicode_ci
# 創建用戶
CREATE USER 'test’@‘localhost’ IDENTIFIED BY ’Test123456@‘;
# 用戶授權該表全部權限
GRANT ALL PRIVILEGES ON mysite_db.* TO ’Test123456@‘;
# 刷新入庫生效
FLUSH PRIVILEGES;
4、數據庫導出導入
# 從開發庫里導出
mysqldump -u root -p mysite_db > data.sql
# 把data.sql文件拷到服務器上(可以用工具,也可以用scp命令)
scp data.sql root@xx.xx.xx.xx:/home/data.sql
# 進入服務器數據庫
mysql -u root -p mysite_db
# 導入數據文件
source data.sql;
5、如果不是通過數據庫導入方式建表的,那重新創建表即可
python3 manage.py makemigrations
python3 manage.py migrate
python3 manage.py createcachetable # 緩存表的名稱需在setting文件里已設置
六、測試啟動
啟動測試下,服務是否正常
python3 manage.py runserver 0.0.0.0:80
七、用Nginx+uWSGI部署
1、安裝uwsgi(可參考官方文檔)
# 安裝uwsig
pip3 install uwsgi
2、基礎測試
創建一個名為 test.py的文件,vim編輯文件:
def application ( env,start_response ):
start_response ('200 OK',[('Content-Type','text / html' )])
return [ b “Hello World” ] #python3
3、測試運行
uwsgi --http:8000 --wsgi-file test.py
# 說明 --http :8000 使用http協議 端口8000 --wsgi-file test.py 加載指定文件
# 如果出現HelloWorld說明可用
# 如果出現--- no python application found, check your startup logs for errors —錯誤,說明python版本有多個,而你的uwsgi不是裝在默認的那個python里,所以可以在虛擬機里創建一個只有一個python的環境啟動,或者在/etc/profile里把python路徑改成安裝uwsgi的python路徑
# 訪問不了,還有可能是服務器沒有開放8000端口,比如阿里云是默認關閉8000端口的,去開啟即可
4、使用uwsgi測試你的項目
# 進入的項目文件夾(與manage.py同一級)
# 確保項目可以正常工作
python3 manage.py runserver 0.0.0.0:8000
# 如果發現django模塊不能導入,則是因為沒有添加環境變量,具體命令如下:vim ~/.bash_profile,添加django的路徑export PATH=$HOME 在此部分添加,用冒號隔開,具體格式請搜索 $PATH。
# 如果地址不能訪問,檢查django項目的settings.py設置,把 ALLOWED_HOSTS = [] 改為 ALLOWED_HOSTS = ['*’]
# 如果還是不能訪問,查看8000端口是否開放
# 用uwsgi運行項目
uwsgi --http :8000 --chdir /home/mysite --home /home/mysite_env --module mysite.wsgi:application
# 上面具體參數設置可見[官方文檔](https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/uwsgi/#configuring-and-starting-the-uwsgi-server-for-django)
5、安裝nginx(CentOS)
# 安裝nginx(已裝過的可略)
# 下載
wget [http://nginx.org/download/nginx-1.14.1.tar.gz](http://nginx.org/download/nginx-1.14.1.tar.gz)
# 解壓
tar -xzvf nginx-1.14.1.tar.gz
# 進入目錄
cd nginx-1.14.1/
# 安裝依賴
yum install -y pcre pcre-devel
yum install -y openssl openssl-devel
# 創建Nginx的用戶組及用戶
groupadd nginx
useradd -s /sbin/nologin -M -g nginx nginx
# 編譯及安裝
./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
make && make install
# 檢查并啟動(以下三個命令都要運行)
/usr/local/nginx/sbin/nginx -t # 測試nginx.conf的配置是否正確
/usr/local/nginx/sbin/nginx # 直接啟動
/usr/local/nginx/sbin/nginx -s reload # 重啟
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf # 根據nginx.conf里的配置,啟動nginx服務
# 具體可參考[Linux(CentOS 6.5) 下Nginx 安裝,重啟和停止](https://blog.csdn.net/greensomnuss/article/details/80986238)
6、配置nginx(CentOS)
# 將/usr/local/nginx/conf目錄下的uwsgi_params文件復制到你的項目目錄
cp /usr/local/nginx/conf/uwsgi_params /home/mysite/
# 創建myconfs文件夾
mkdir /home/myconfs
# 創建一個名為mysite_nginx.conf的文件(可以在任意路徑,只要你能找到,這里我把它放在/home/myconfs/)
vim /home/myconfs/mysite_nginx.conf
# 按自己路徑寫入配置信息(如下)
具體配置(可見nginx文檔)
upstream django {
# server unix:///path/to/your/mysite/mysite.sock; # for a file socket
server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}
# configuration of the server
server {
# 你的網站監聽的端口,此處先用8000端口測試,正式部署可以改為80或其他
listen 8000;
# 你的網站的域名
server_name *.com; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias /home/mysite/media; # 你的media的文件目錄
}
location /static {
alias /home/mysite/collected_static; # 你的項目收集的靜態文件目錄(后邊會將收集靜態文件)
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /home/mysite/uwsgi_params; # uwsgi_params 文件所在目錄
}
}
# 這個配置文件告訴nginx提供來自文件系統的媒體和靜態文件,以及處理那些需要Django干預的請求。對于一個大型部署,讓一臺服務器處理靜態/媒體文件,讓另一臺處理Django應用,被認為是一種很好的做法,但是現在,這樣就好了。
讓nginx的根文件載入你的mysite_nginx.conf配置的信息:
vim /usr/local/nginx/conf/nginx.conf
7、部署靜態文件
# 在運行nginx之前,你必須收集所有的Django靜態文件到靜態文件夾里
# 編輯項目的settings
vim /home/mysite/mysite/settings.py
#添加
STATIC_ROOT = os.path.join(BASE_DIR, "collected_static/")
# 然后運行(如果之前用虛擬環境的,記得進入虛擬環境再操作)
python3 manage.py collectstatic
8、基本的nginx測試
# 啟動nginx
/usr/local/nginx/sbin/./nginx
# 如果已經啟動,則重啟
/usr/local/nginx/sbin/./nginx -s reload
# 要檢查是否正確的提供了媒體文件服務,上傳一張圖片(這里我上傳的文件為 1.jpg)到 /home/sysite/media文件夾中
# 然后訪問[http://example.com:8000/media/1.jpg](http://example.com:8000/media/1.jpg) - 如果這能正常工作,那么至少你知道nginx正在正確的提供文件服務。
# 最好將你的nginx先停止, 再開啟,而不是重載
9、配置uwsgi,創建ini文件方便處理。ini參考如下
創建一個名為mysite_uwsgi.ini的文件
[uwsgi]
chdir = /home/mysite # 你的項目目錄
home = /home/mysite_env # 如果有虛擬環境,則需要指定虛擬環境目錄; 沒有則注釋掉
module = mysite.wsgi:application # 指向自己Django項目目錄下mysite目錄下的wsgi文件
master = True
processes = 4 # 使用進程數
harakiri = 60 # 最大超時時間
max-requests = 5000 # 最大請求數,到了后就會自動重啟
socket = 127.0.0.1:8001 # socket連接地址和端口,和之前nginx配置一致
pidfile = /home/mysite_uwsgi/master.pid # 在失去權限前,將pid寫到指定的pidfile文件中
daemonize = /home/mysite_uwsgi/mysite.log # 使進程在后臺運行,并將日志打到指定的日志文件或者udp服務器
# chmod-socket = 664 # 如果沒有權限訪問uWSGI的socket,這里可以設置權限
vacuum = True # 服務退出或重啟,自動刪除pid和socket文件
10、運行uWSGI
uwsgi -d --ini mysite_uwsgi.ini
# 參數 -d 為后臺運行。此時你的django項目已經部署成功。
# 注意,必須nginx也要啟動才能正常訪問
11 、官方參考地址
nginx測試命令:nginx -t
查看uwsgi進程:ps -aux | grep uwsgi
正常關閉uwsgi進程:uwsgi --stop /home/mysite_uwsgi/master.pid
強制關閉全部uwsgi進程:ps -aux | grep uwsgi |awk '{print $2}'|xargs kill -9
重新加載uwsgi:uwsgi --reload /home/mysite_uwsgi/master.pid
參考文檔:
(Django官網)https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/uwsgi/
(uwsgi中文)https://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/tutorials/Django_and_nginx.html
(uwsgi英文)https://uwsgi.readthedocs.io/en/latest/tutorials/Django_and_nginx.html
(自強學堂)https://code.ziqiangxuetang.com/django/django-nginx-deploy.html
八、使用Nginx+Gunicorn部署(其他方案)
可參考:Centos上Python應用部署詳情(Nginx 和 Gunicorn 部署 Django項目)
九、配置清單(發布環境配置修改)
1、開發環境和生產環境配置分開
把原先的settings.py改名為settings_base.py,創建settings_development.py和settings_production.py文件。把基礎共用的配置保留在base文件里,在development文件里只保留Degbu、DATABASES等其他需單獨配置的設置,在production文件里同樣,development和production繼承base文件。注意配置不要重復
2、修改生產環境的配置:秘鑰不明文顯示
- 修改Debug為False
-
重新生成SECRET_KEY秘鑰,并設置從環境變量里讀取的方式獲取(不在配置文件里明文顯示)
- 數據庫密碼也一樣,從環境變量里讀取的方式獲取(不在配置文件里明文顯示)
- 郵箱的授權碼也一樣設置
# 重新生成秘鑰方法
from django.core.management import utils
utils.get_random_secret_key() # 該方法可以生成秘鑰
# linux里設置環境變量
vim /etc/profile
# 在文件最后面加上配置(如下圖)
# 然后生效
source /etc/profile
3、修改生產環境的配置:增加日志文件配置(官方文檔說明)
在settings_production.py文件最后增加日志配置
# 日志配置,若需要其他設置,可參考官方文檔
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': ‘/home/mysite_debug.log',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
},
}
在服務器上創建并修改mysite_debug.log文件的權限
chmod 666 mysite_debug.log
4、修改生產環境的配置:更改郵件設置的端口和認證方式
有些云服務器對25端口有嚴格的限制,所以我們把端口和認證方式改成SSL的:
# 端口改成465,記得在服務器上把465端口開放
EMAIL_PORT = 465
# EMAIL_USE_TLS 改成 EMAIL_USE_SSL
EMAIL_USE_SSL = True
5、增加404、500錯誤頁面
把404.html和500.html等文件放到templates根目錄下即可
6、增加favicon.ico圖標(瀏覽器圖標)
- 第一種方法(這種方法可行):
把favicon.ico圖標放到項目misite目錄下(目錄可以自定),然后同步到GITHUB,服務器pull同步數據
編輯nginx配置文件(vim /home/myconfs/mysite_nginx.conf):
location /favicon.ico {
# 你的favicon.ico文件path
alias /home/mysite/mysite/favicon.ico;
}
- 第二種方法(這個方法我在開發環境可以,部署到生產環境還是不行):
把favicon.ico文件放到根目錄的static目錄下,然后修改urls.py,如下
from django.contrib.staticfiles.views import serve
urlpatterns = [
...
path('favicon.ico', serve, {'path': 'favicon.ico'}),
]
- 第三種方法(這種方法可以用,但admin管理界面里默認是沒有這個文件的)
# 修改base.html文件,在head里增加讀取favicon.ico
<link href="{%static "favicon.ico" %}" rel="shortcut icon"/>
7、設置上傳文件目錄的權限
# 修改media目錄的權限
chmod 777 media/
8、重新匯聚靜態文件
python3 manage.py collectstatic
9、重啟nginx和uwsgi測試
十、正常運行后發現的問題記錄和處理
1、django-ckeditor插件里上傳圖片是報server 500錯誤
解決方法:網上有說把media文件夾權限改成777,但我不行,我把/usr/local/nginx/conf/nginx.conf配置文件里第一行原值#user nobody; 修改為 user root;并保存。使用 /usr/local/nginx/sbin/nginx -s reload 命令重新加載配置文件即可。
但我不想用root,但試了改成nginx用戶等都不行,暫時沒有找到其他辦法。
2、我們在頁面編輯的時候,總是要寫代碼的,但現在的django-ckeditor插件還沒有設置插入代碼的功能
解決方法:在settings設置里,修改CKEDITOR_CONFIGS的設置:
CKEDITOR_CONFIGS = {
'default': {
'width': 'auto',
'toolbar': (
['div', 'Source', '-', 'Preview'],
['Copy', 'Cut', 'Paste', 'PasteText', 'PasteFromWord',],
['Undo', 'Redo', '-', 'Find', 'Replace', '-', 'SelectAll', 'RemoveFormat'],
['Bold', 'Italic', 'Underline', 'Strike', '-', 'Subscript', 'Superscript'],
['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', 'Blockquote'],
['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
['Link', 'Unlink', 'Anchor'],
['Image', 'Flash', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak'],
['Styles', 'Format', 'Font', 'FontSize'],
['TextColor', 'BGColor'],
['Maximize', 'ShowBlocks', '-', 'About'],
['CodeSnippet', '-', 'Print'],
),
# 插件
'extraPlugins': ','.join(['codesnippet', 'prism', 'widget', 'lineutils', ]),
},
}
# 其中插件codesnippet既是代碼編輯功能,記得在toolbar里加上'CodeSnippet’按鈕
# prism為代碼高亮插件
3、加了codesnippet后,可以編輯代碼了,但當非編輯狀態下看的時候,發現代碼沒有高亮顯示,不美觀
解決方法:增加prism插件(詳細步驟可見這篇文章).
從ckeditor官網下載 插件prism(點這里直接下載),然后將其解壓到ckeditor/static/ckeditor/ckeditor/plugins路徑下,同樣的我們需要在CKEDITOR_CONFIGS里將extraPlugins對應的value里加入插件 'prism' 和另外兩個插件"lineutils"、"widget" ,這兩個插件無須下載,在django-ckeditor中已經有了.
去prismjs官網下載css文件http://prismjs.com/download.html,選擇你喜歡的主題,勾選支持的語言,以及別忘選擇line-numbers功能,下載后把他解壓到自己項目的static/下
然后在模板中引用靜態文件即可