一、背景
最近在學習Python和Django,並且把以前用java做過的一個后台管理系統改造成了Python3.6+Django2.0的版本,做完了當然是要把它部署到自己的服務器上才像樣嘛!想到自己正好有個VPS服務器(用來VPN科學上網的~~),這個服務器以前部署過java應用,所以mysql都已經安裝好了的,省了好大一件事~~(Mysql安裝詳見我之前的博客阿里雲服務器搭建經歷),所以我們只需要搞好Django應用部署相關的東西就好啦。
二、安裝相關軟件
1、安裝Python3
由於我使用的服務器發行版本是CestOS7,其他Linux發行版本都是類似的安裝模式,只是命令有稍微的區別而已,稍微百度一下就可以了。
首先,我們要安裝Python,一般Linux服務器都會有個默認的Python,我的VPS里面安裝的是Python2.7,由於我使用的是Python3,所以需要重新安裝,各位可以根據自己具體需求選擇安裝。安裝Python也很簡單,直接使用命令:
1 yum install python36u
安裝Python3完成后的shell命令為python3.6,為了使用方便,創建一個到python3的符號鏈接
1 sudo ln -s /bin/python3.6 /bin/python3
2、安裝pip3
Python3安裝完成后並沒有安裝Python的包管理工具pip3,所以我們需要安裝一下,直接使用命令安裝:
1 yum install python36u-pip
安裝pip完成后的shell命令為pip3.6,為了使用方便,創建一個到pip3的符號鏈接
1 ln -s /bin/pip3.6 /bin/pip3
如有提示pip版本過低,可以使用以下命令更新pip版本
1 pip3 install --upgrade pip
3、虛擬環境安裝和使用
直接使用命令安裝虛擬環境
1 pip3 install virtualenv
安裝完成后,需要創建一個虛擬環境
1 virtualenv weiyaqi_env
啟動虛擬環境
1 source bin/activate
退出虛擬環境
1 deactivate
在虛擬環境將本項目需要的python包安裝進去,使用命令生成requirements.txt
1 pip freeze > requirements.txt
使用requirements.txt安裝該虛擬環境所有需要的包
1 pip install -r requirements.txt
其中有個包比較特殊,通過requirements.txt安裝不了,需要特殊處理,那就是mysqlclient(會報GCC相關的錯誤),所以只能通過以下方式進行安裝
1 yum install python36u python36u-devel 2 yum install gcc mariadb-devel 3 pip3 install mysqlclient
4、git安裝與使用
安裝git也直接使用命令安裝
1 yum install git
安裝完成后便可以克隆代碼到服務器了
git clone https://github.com/xxx/xxProject.git
如果代碼有更新,可以使用命令拉取最新代碼
1 git pull
5、Apache相關環境搭建
1 yum install httpd
設置Apache服務開機自啟動(可選,不過設置自啟動方便)
1 /sbin/chkconfig httpd on
啟動Apache服務
1 /sbin/service httpd start
安裝httpd-devel
1 yum install -y httpd-devel
安裝mod__wsgi
1 wget https://codeload.github.com/GrahamDumpleton/mod_wsgi/tar.gz/4.6.4 2 tar zxvf 4.6.4 3 cd mod_wsgi-4.6.4 4 ./configure --with-apxs=/usr/bin/apxs --with-python=/usr/bin/python3.6 5 make 6 make install
從github下載下來的文件是4.6.4,解壓后就是mod_wsgi-4.6.4
在apache配置文件最后追加一行
1 vim /etc/httpd/conf/httpd.conf 2 # 追加一行 3 LoadModule wsgi_module /usr/lib64/httpd/modules/mod_wsgi.so
重啟Apache服務
1 systemctl restart httpd
清理編譯后的源代碼
1 make clean
Apache配置應用相關配置(新建一個.conf文件)
1 cd /etc/httpd/conf.d/ 2 vim weiyaqi.conf
文件內容如下
1 <VirtualHost *:80> 2 WSGIScriptAlias /weiyaqi /home/pythonSources/content_manage/content_manage/wsgi.py 3 WSGIDaemonProcess weiyaqi python-home=/home/weiyaqi_env python-path=/home/pythonSources/content_manage 4 WSGIProcessGroup weiyaqi 5 6 <Directory /home/pythonSources/content_manage/content_manage> 7 <Files wsgi.py> 8 Require all granted 9 </Files> 10 </Directory> 11 # 開放靜態目錄 12 Alias /static/ /home/pythonSources/content_manage/static/ 13 Alias /media/ /home/pythonSources/content_manage/media/ 14 <Directory /home/pythonSources/content_manage/static> #設置靜態文件目錄訪問權限 15 Require all granted 16 </Directory> 17 <Directory /home/pythonSources/content_manage/media> #設置媒體文件訪問權限 18 Require all granted 19 </Directory> 20 </VirtualHost>
重啟Apache服務即可
然而這樣應用可以訪問,但是很多靜態文件都找不到,所以需要對靜態文件進行收集到一個文件夾中,並且在該項目的.conf文件中指定這個收集到的靜態文件夾。
setting.py添加:
1 STATIC_ROOT = os.path.join(BASE_DIR, 'static_collected')
進入到虛擬環境中對靜態文件進行收集
1 python3.6 manage.py collectstatic
修改apache配置中靜態文件目錄
1 <VirtualHost *:80> 2 WSGIScriptAlias /weiyaqi /home/pythonSources/content_manage/content_manage/wsgi.py 3 WSGIDaemonProcess weiyaqi python-home=/home/weiyaqi_env python-path=/home/pythonSources/content_manage 4 WSGIProcessGroup weiyaqi 5 6 <Directory /home/pythonSources/content_manage/content_manage> 7 <Files wsgi.py> 8 Require all granted 9 </Files> 10 </Directory> 11 # 開放靜態目錄 12 Alias /static/ /home/pythonSources/content_manage/static_collected/ 13 Alias /media/ /home/pythonSources/content_manage/media/ 14 <Directory /home/pythonSources/content_manage/static_collected> #設置靜態文件目錄訪問權限 15 Require all granted 16 </Directory> 17 <Directory /home/pythonSources/content_manage/media> #設置媒體文件訪問權限 18 Require all granted 19 </Directory> 20 </VirtualHost>
另外,服務器可能會存在端口未開放的問題,可以在/var/log/httpd/error.log查看Apache的錯誤日志,通過修改iptables可以對部分端口進行開放,如果是阿里雲的服務器,可以直接通過控制台修改(方法百度應該會有很多,這里就不再贅述了!)使用iptables設置端口訪問
1 vim /etc/sysconfig/iptables 2 # 開放80端口 3 -A INPUT -p tcp --dport 80 -j ACCEPT
三、部署多個應用的問題
1、多個應用部署配置
上面說到了,部署一個應用的時候,我們在配置里面新增了一個.conf的配置文件。所以,部署第二個應用的時候同樣可以再新增一個.conf的配置文件,配置是類似的,只是在VirtualHost *:80這個地方后面跟的端口要配置的不一樣,並且在Apache的主配置文件/etc/httpd/conf/httpd.conf中新添加一個監聽端口,並且還需要在iptables配置中開放此端口
2、兩個應用同時登錄的問題
如果我們有兩個django應用site1和site2同時跑在同一個server的不同端口,同時我們在同一個瀏覽器的不同tab登錄。那么這時就出出現這種情況,當我們登錄site2時就會將site1上登錄的用戶踢下來。為什么會出現這種情況呢?這跟django的session框架有關,這里做一個簡單介紹:當我們第一次訪問一個django網站時,django會生成一個session來保存當前會話的一些信息。同時會生成一個哈希值。
為什么會出現這種情況呢?這跟django的session框架有關,這里做一個簡單介紹:當我們第一次訪問一個django網站時,django會生成一個session來保存當前會話的一些信息。同時會生成一個哈希值session_key並生成一個cookie發送給客戶端,這個cookie的名字根據setting中SESSION_COOKIE_NAME設置,默認為“sessionid”(划重點)。這樣下次請示session_key就會跟隨cookie發送到server。server根據session_key查找對應session對象,獲取當前會話的信息,當然也包括登錄信息。我們登錄site1是得到一個叫sessionid的cookie,里面存儲session_key1。當我們登錄site2時會更新那個叫sessionid的cookie,現在它的值為session_key2(瀏覽器存儲cookies是基於ip而不是端口,所以會更新同一個名字的cookie)。
所以現在用新的session_key訪問site1時就會拿不到原來的登錄信息,需要我們重新登錄。那么怎么解決呢,了解上面機制后,只需要在setting中設置SESSION_COOKIE_NAME即可。比如可以在site2中設置SESSION_COOKIE_NAME = ‘site2’,site1中用默認。當然同時設置site1和site2。
3、安全問題
在將Django應用部署到服務器上時,為了安全,最好是重新生成一個secret_key, 生成方式如下
1 from django.core.management import utils 2 utils.get_random_secret_key()
啊!碼字好累,自己都感覺好亂,希望大家能夠看懂~~~