Django項目在Linux服務器上部署和躺過的坑


  引言

  在各方的推薦下,領導讓我在測試環境部署之前開發的測試數據預報平台。那么問題來了,既然要在服務器上部署,

就需要准備:

1.linux服務器配置

2.linux安裝python環境搭建與配置

3.項目依賴的庫

4.uwsgi安裝與配置

5.nginx安裝與配置

 

  環境安裝

備注:以下所有操作都在root權限下進行,如果沒有linux的root權限,找運維或者相關人員開通。

1.更新系統軟件包

[root@localhost ~]# yum update -y

2.安裝軟件管理包和可能使用的依賴

[root@localhost ~]#  yum -y groupinstall "Development tools"
[root@localhost ~]# yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel psmisc libffi-devel

敲黑板:centos安裝python3.7時遇到如下問題,查閱知需要的openssl版本最低為1.0.2,但是centos 默認的為1.0.1,所以需要重新更新openssl

import _ssl       # if we can't import it, let the error propagate
ImportError: No module named _ssl

3.安裝依賴庫

[root@localhost ~]# yum install -y zlib zlib-dev openssl-devel sqlite-devel bzip2-devel libffi libffi-devel gcc gcc-c++

4.安裝最新版本的openssl 注意!openssl配置是用config,而不是configure,另外openssl編譯安裝依賴zlib動態庫,所以一定要shared zlib 自行到官網查閱最新版本~

wget http://www.openssl.org/source/openssl-1.1.1.tar.gz
tar -zxvf openssl-1.1.1.tar.gz
cd openssl-1.1.1
./config --prefix=$HOME/openssl shared zlib
make && make install

敲黑板:安裝python前一定要先安裝ssl,不然后面pip使用不了。

5.設置環境變量LD_LIBRARY_PATH

 

echo "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/openssl/lib" >> $HOME/.bash_profile
source $HOME/.bash_profile

 

這一步一定要有!!LD_LIBRARY_PATH環境變量主要用於指定查找共享庫(動態鏈接庫)時除了默認路徑之外的其他路徑。當執行函數動態鏈接.so時,如果此文件不在缺省目錄下‘/lib' and ‘/usr/lib',那么就需要指定環境變量LD_LIBRARY_PATH
6.解壓python3.7,並安裝,一定要指定剛才安裝的1.1.1版本的openssl!!!
敲黑板:這里安裝python后面一定要指定--with-openssl=$HOME/openssl ,其中$HOME就是/root目錄
tar -zxvf Python-3.7.0.tgz
./configure --prefix=$HOME/Py37 --with-openssl=$HOME/openssl
make && make install
echo $HOME

7.至此python3.7就安裝完了,來檢驗下ssl模塊能否被導入吧:

[root@test-bss-181 ~]# echo $HOME
/root
[root@test-bss-181 ~]# cd /root/Py37/
[root@test-bss-181 Py37]# ls
bin  include  lib  share
[root@test-bss-181 Py37]# cd bin/
[root@test-bss-181 bin]# ls
2to3      easy_install-3.7  idle3.7  pip3    pydoc3    python3    python3.7-config  python3.7m-config  pyvenv      virtualenv
2to3-3.7  idle3             pip      pip3.7  pydoc3.7  python3.7  python3.7m        python3-config     pyvenv-3.7
[root@test-bss-181 bin]# ./python3
Python 3.7.0 (default, Jan 12 2020, 03:54:25) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-23)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl
>>> import _ssl
>>> 

已經驗證沒有報錯。

如果沒有按照步驟安裝,將出現:

>>> import ssl
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "D:\Anaconda\lib\ssl.py", line 98, in <module>
    import _ssl             # if we can't import it, let the error propagate
ModuleNotFoundError: No module named '_ssl'
>>>

最后使用pip安裝其他包會出現:

這里是個坑,所以在此講一下,可能有人會遇到。接下來繼續講

8.python安裝好后,要創建軟鏈接,你若要不知道python的位置在哪兒可以這樣

[root@izbp12am8wqrn7t6wzgmydz bin]# whereis python
python: /usr/bin/python /usr/bin/python2.7 /usr/bin/python.bak /usr/lib/python2.7 /usr/lib64/python2.7 /etc/python /usr/include/python2.7 /usr/local/python /usr/share/man/man1/python.1.gz

查看軟鏈接指向

[root@root ~]# cd /usr/bin/
[root@root bin]# ll python*
lrwxrwxrwx. 1 root root    7 2月   7 09:30 python -> python2
lrwxrwxrwx. 1 root root    9 2月   7 09:30 python2 -> python2.7
-rwxr-xr-x. 1 root root 7136 8月   4 2017 python2.7
可以看到,python指向的是python2,python2指向的是python2.7,因此我們可以裝個python3,然后將python指向python3,然后python2指向python2.7,那么兩個版本的python就能共存了。
添加python軟鏈接
將原來的鏈接備份
mv /usr/bin/python /usr/bin/python.bak

添加python3的軟鏈接
ln -s /root/Py37/bin/python3.7 /usr/bin/python

測試是否安裝成功了
python -V

添加pip軟鏈接

ln -s /root/Py37/bin/pip3.7 /usr/bin/pip

[root@test-bss-181 bin]# ll pip*
lrwxrwxrwx  1 root root 21 Jan 12 04:03 pip -> /root/Py37/bin/pip3.7

9.安裝virtualenv ,建議大家都安裝一個virtualenv,方便不同版本項目管理

[root@localhost /]# pip3 install virtualenv

10.建立軟鏈接

[root@localhost /]# ln -s /root/Py37/bin/virtualenv /usr/bin/virtualenv

 11.安裝成功在根目錄下建立兩個文件夾,主要用於存放env和網站文件的。(個人習慣,其它人可根據自己的實際情況處理),建立文件夾是切換到根目錄。

1 [root@localhost /]# mkdir -p /www/env
2 [root@localhost /]# mkdir -p /www/wwwroot

 

12.切換到/www/env/下,創建指定版本的虛擬環境,為python3指定虛擬環境,因為虛擬環境也可以有多個。

virtualenv --python=/usr/bin/python3 mysite
#mysite是我項目名稱

例如:

 

 

13.然后進入/www/env/mysite/bin ,啟動虛擬環境:

(mysite) [root@localhost myblog]# source mysite/bin/activate

 

注意:有個括號里面並且是之前設置的名稱,證明你已經成功進入虛擬環境

以上環境是基本上搭建完成了,如有遺漏請留言,后續補充。

接下來就是項目部署與配置

 

 

 

  項目部署

敲黑板:django項目部署啟動方式有很多種,這里我只講三種最基本的,如有更快捷的方式請留言,感激不盡!

  原始啟動

1. 簡單粗暴

項目開發完畢,在部署之前需要再配置文件中將 ALLOWED_HOSTS配置設置為:當前服務器IP或*,如:

 

ALLOWED_HOSTS = ["*",]

然后將源碼上傳至服務器指定目錄,如:/data/ ,然后執行命令來運行:

注: 上傳命令: scp /Users/wupeiqi/PycharmProjects/oldboy-1.zip root@192.168.10.33:/data/

可以在windows安裝git,然后使用scp,windows自帶的命令不支持。

解壓,進入目錄並執行以下命令:

python3 mange.py runserver 0.0.0.0:8000

 

 

 

  Uwsgi啟動Django項目

1. Uwsgi

先簡單了解一下uwsgi,uWSGI:是一個web服務器,實現了WSGI協議、uwsgi協議、http協議等。它是線路協議,是實現服務器與其他網絡服務器通信的協議,可以看作Tomcat。

Django框架運行依賴wsgi(本質提供socket服務端),眾多模塊實現了wsgi規范,而django框架中默認使用wsigiref模塊來實現,他由於性能比較低,所以用於本地開發和測試,而線上部署時需要使用uwsgi來代替。

2.安裝uwsgi

pip3 install uwsgi

3.在服務器上編寫一個Python文件:

def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"]

在服務器上執行命令啟動Web服務器:

uwsgi --http :9001 --wsgi-file app.py
#
uwsgi --http :9002 --wsgi-file foobar.py --master --processes 4

 

 

 

敲黑板:這里使用http的,並且ip地址是服務器的ip,本機訪問,需要加上端口號,如訪問不了,請確保命令中的端口是否被占用!

 

 

 

4.Django項目使用uswgi啟動

在項目的根目錄下,也就是manage.py同級目錄下,新建一個" uwsgi.ini "文件。文件名可以隨便,但擴展名必須是".ini"

 1 [uwsgi]
 2 socket = 192.168.1.2:8000                  #應用服務IP端口
 3 chdir = /pyvenv/src/eduonline              #項目根目錄
 4 module = eduonline.wsgi                #指定wsgi模塊,與Nginx連接時用
 5 #http = IP:Port                            #web服務IP端口,uWSGI做web服務器時用
 6 master = true                              #進程
 7 processes = 4                              #進程數
 8 
 9 #vhost = true                              #多站模式
10 #no-site = true                            #多站模式時不設置入口模塊和文件
11 #workers = 2                               #子進程數
12 #reload-mercy = 10
13 #vacuum = true                             #退出、重啟時清理文件
14 #max-requests = 1000
15 #limit-as = 512
16 #buffer-size = 30000
17 
18 #進程文件,新建空文件即可,用於服務重啟、停止。如:
19 #重啟指令:uwsgi --restart [pidfile路徑]
20 #停止指令:uwsgi --stop [pidfile路徑]
21 pidfile = /pyvenv/src/eduonline/uwsgi.pid      
22 daemonize = /pyvenv/src/eduonline/uwsgi.log     #日志文件,一般會自動創建
23 #disable-logging = true                         #不記錄正常信息,只記錄錯誤信息

類似版本:

 1 [uwsgi]
 2 #項目的根目錄
 3 chdir = /home/my_project/django_demo
 4  
 5 #項目的對接wsgi.pi文件
 6 module = django_demo.wsgi:application
 7  
 8 #項目執行的變口號,和nginx配置的要一致
 9 socket = 127.0.0.1:8000
10  
11 #是否以主進程模式允許
12 master = true
13  
14 #開啟的工作進程數量
15 processes=4   
16  
17 #日志文件路徑,前提是該文件要存在,且可寫
18 daemonize = /home/my_project/django_demo/run.log
19  
20 #表示不記錄正常信息,只記錄錯誤信息,否則你的日志可能很快就爆滿
21 disable-logging = true
22  
23 #當服務器退出的時候自動清理環境
24 vacuum = true
25  
26 #進程信息文件路徑(這里指項目的根目錄)
27 pidfile=%(chdir)/uwsgi.pid
View Code

敲黑板:這里有個坑,如果單純把uwsgi作為web服務器的話,不搞nginx的話,要配置成http = ip:port,而不是socket = 192.168.1.2:8000,不然你哭死都無法訪問,即使一切看起來正常,也沒報錯!

 

 配置好了就可以啟動

uwsgi --ini uwsgi.ini

進入項目根目錄(uwsgi.ini存放的目錄),和manag.py同級目錄,輸入

uwsgi --ini ./uwsgi.ini

 

 這樣代表啟動正常了。

不放心,可以使用命令進行查看:

netstat -anp|grep 9527
#殺進程 
kill -9 pid

 

 輸入ip+端口,通過瀏覽器可以訪問

 

 

 敲黑板:這里也有個坑,只用uwsgi作為web訪問,在之前uwsgi.ini文件里,配置的服務器地址一定要是服務器真實IP地址,不能是localhost或127.0.0.1,不然你本機無法從瀏覽器訪問了。

例如:

 

 

 

 總結一下常用操作命令:

# 啟動uwsgi
uwsgi --ini uwsgi.ini
# 關閉uwsgi uwsgi --stop ./uwsgi.pid
# 重啟 uwsgi --reload ./uwsgi.pid
#查看確認是否uwsgi啟動 ps -ef|grep uwsgi
#查看端口是否起來 netstat -anp|grep 9527

 

  靜態文件處理

 啟動之后你會頁面靜態文件沒有加載,在生產上部署和開發模式加載靜態文件方式是不一樣的。

1.首先,我們配置靜態文件,要在setting.py里面加入如下幾行代碼:

STATIC_ROOT = os.path.join(BASE_DIR, 'collect_static')

2.進入到項目根目錄,創建文件夾collect_static

mkdir collect_static

3.靜態文件遷移

python manage.py collectstatic

django會把所有的static文件都復制到STATIC_ROOT文件夾下

STATIC_ROOT 是在部署靜態文件時(pyhtonmanage.pycollectstatic)所有的靜態文靜聚合的目錄,STATIC_ROOT要寫成絕對地址,在這里,比如我的項目mysite是/home/mysite/
那么STATIC_ROOT 為 /home/mysite/collect_static/

說明:

STATIC_ROOT 是在部署的時候才發揮作用, 而實際情況下,靜態文件的一般安放位置有兩種:

1.一種就是在每個app里面新建一個static文件夾,將靜態文件放到里面,在加載靜態文件時,比如要在模板中用到靜態文件,django會自動在每個app里面搜索static文件夾(所以,不要把文件夾的名字寫錯哦, 否則django就找不到你的文件夾了)

2.另一種,就是在所有的app文件外面,建立一個公共的文件夾, 因為有些靜態文件不是某個app獨有的,那么就可以把它放到一個公共文件夾里面,方便管理(注意,建立一個公共的靜態文件的文件夾只是一種易於管理的做法,但是不是必須的,app是可以跨app應用靜態文件的,因為最后所有的靜態文件都會在STATIC_ROOT里面存在)
那現在的問題是如何讓django知道你把一些靜態文件放到app以外的公共文件夾中呢,那就需要配置STATICFILES_DIRS了

進入文件夾collect_static后查看

 

 

 

 全部遷移過來了,再次刷新瀏覽器,頁面靜態文件加載成功。

至此,uwsgi部署已完成

 

  

可能遇到的問題:

1、啟動uwsgi報錯信息:

(autoforedata) [root@test-bss-181 autoforecastdata]# uwsgi --ini uwsgi.ini
[uWSGI] getting INI configuration from uwsgi.ini
*** WARNING: Can't find section "uwsgi" in INI configuration file uwsgi.ini ***
*** Starting uWSGI 2.0.18 (64bit) on [Tue Jan 14 09:43:30 2020] ***
compiled with version: 4.4.7 20120313 (Red Hat 4.4.7-23) on 13 January 2020 08:58:36
os: Linux-2.6.32-696.el6.x86_64 #1 SMP Tue Mar 21 19:29:05 UTC 2017
nodename: test-bss-181
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 8
current working directory: /data/wwwroot/autoforecastdata
detected binary path: /data/env/autoforedata/bin/uwsgi
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
*** WARNING: you are running uWSGI without its master process manager ***
your processes number limit is 63718
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
The -s/--socket option is missing and stdin is not a socket.

解決方案:

  • 1.增加用戶和組,具體命令如下:
/usr/sbin/groupadd www
/usr/sbin/useradd -g www www
  • 2.增加了www的用戶名和組,之后修改uWsgi配置文件:
 這是我之前的配置
[uwsgi]
uid = root gid = root
現在改成這樣
[uwsgi]
uid = www
gid = www

之后重啟一下uWsgi,即可

[uwsgi-static] added mapping for /static => /data/wwwroot/autoforecastdata/collect_static   #出現這個就是正常

 

2.還有一種報錯,沒有在項目根目錄下啟動

(autoforedata) [root@test-bss-181 sbin]# uwsgi --ini uwsgi.ini
realpath() of uwsgi.ini failed: No such file or directory [core/utils.c line 3654]

cd到項目所在根目錄下啟動。(命令不要有空格,如果不行,將ini文件的所有注釋清除!)

3.啟動正常,當項目后台調用其他服務接口出現:訪問提示openurl錯誤,或者是沒有服務或服務名

這種情況是由於訪問的域名沒有映射對應的服務器IP地址

進入

cd /etc/

編輯hosts文件

vi hosts

加入映射關系即可

 

 

  Uwsgi + Nginx的部署

上面是uwsgi的啟動方式,一般不考慮安全、負載均衡和代理的話,就不需要結合nginx來部署。

這里介紹uwsgi+nginx的部署:

1.首先是按照nginx程序

[root@localhost ~]# cd /home/
[root@localhost home]# wget http://nginx.org/download/nginx-1.13.7.tar.gz
[root@localhost home]# tar -zxvf nginx-1.13.7.tar.gz
[root@localhost home]# cd nginx-1.13.7
[root@localhost nginx-1.13.7]# ./configure
[root@localhost nginx-1.13.7]# make
[root@localhost nginx-1.13.7]# make install

2.nginx一般默認安裝好的路徑為/usr/local/nginx,在/usr/local/nginx/conf/中先備份一下nginx.conf文件,以防意外。

[root@localhost nginx]# cp nginx.conf nginx.conf.bak

 

 

 

 

 3.配置nginx,這里是關鍵,然后打開nginx.conf,把原來的內容刪除,直接加入以下內容:

events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    server {
        listen 80;
        server_name  127.0.0.1:80; #改為自己的域名,沒域名修改為127.0.0.1:80
        charset utf-8;
        location / {
           include uwsgi_params;
           uwsgi_pass 127.0.0.1:8997;  #端口要和uwsgi里配置的一樣
           uwsgi_param UWSGI_SCRIPT mysite.wsgi;  #wsgi.py所在的目錄名+.wsgi
           uwsgi_param UWSGI_CHDIR /www/wwwroot/myblog/; #項目路徑
           
        }
        location /static/ {
        alias /www/wwwroot/myblog/static/; #靜態資源路徑
        }
    }
}

要留意備注的地方,要和UWSGI配置文件myblog.xml,還有項目路徑對應上。
進入/usr/local/nginx/sbin/目錄
執行./nginx -t命令先檢查配置文件是否有錯,沒有錯就執行以下命令:

[root@localhost sbin]# ./nginx 

有時候改了配置后會報這樣的錯誤:

(autoforedata) [root@test-bss-181 sbin]# ./nginx -s reload
nginx: [emerg] unknown directive "events" in /usr/local/nginx/conf/nginx.conf:1

這個時候將原來的配置文件conf刪除,將之前備份的重新弄一份,cp進去,然后配置一下之前的內容,配置文件里面的內容不正確很容易報錯,注意一些細節,比如空格。

敲黑板:這套部署setting.py需要設置成:

1、關閉DEBUG模式。

DEBUG = False

2、ALLOWED_HOSTS設置為* 表示任何IP都可以訪問網站。

ALLOWED_HOSTS = [’*’]

 

常用命令集:

啟動服務:nginx
退出服務:nginx -s quit
強制關閉服務:nginx -s stop
重啟服務:nginx -s reload
驗證配置文件:nginx -t
使用配置文件:nginx -c "配置文件路徑"
使用幫助:nginx -h


netstat -nupl (UDP類型的端口)
netstat -ntpl (TCP類型的端口)
netstat -anp 顯示系統端口使用情況

(autoforedata) [root@test-bss-181 autoforecastdata]# netstat -anp|grep nginx
(autoforedata) [root@test-bss-181 autoforecastdata]# netstat -anp|grep 8090
tcp        0      0 0.0.0.0:8090                0.0.0.0:*                   LISTEN      20985/nginx

ps -aux|grep 進程名

 

 

  內網映射

 這里還需要注意,如果你公司有域名服務器,請運維給你弄個域名,做內網映射。那么內網任何一台電腦都可以通過域名訪問了,不需要每台電腦配置域名映射(在hosts文件里配置服務器IP與域名映射關系),當然如果沒有域名,那就只能通過服務器IP來訪問了。

 

 如圖/etc/hosts文件

 

 

 如圖:/usr/local/nginx/conf配置:

 

 瀏覽器域名訪問:

 

 

 

完結!

 

PS:部署過程蹲過很多坑耗時太久,為了方便以后使用,所以用文字來記錄一下。如果您看完該篇,能幫上您,麻煩點個贊,如有不明白地方,可以留言咨詢! 謝謝!

 

 

 

 

 

 

 

 

 

 

資料查詢鏈接:

1.無法導入sll和_ssl報錯問題:https://www.jianshu.com/p/3ec24f563b81

2.刪除linux服務器上yum和python2后導致無法安裝其他(重裝python和yum):

https://www.jianshu.com/p/dad58d810734

https://blog.csdn.net/qq_34646546/article/details/90714946

3.cento6部署django詳細步驟

https://blog.csdn.net/weixin_43883625/article/details/100715363

https://www.cnblogs.com/chaoqi/p/11103188.html

4.CentOS6.5 安裝openssl(可能有坑)

https://www.cnblogs.com/hunttown/p/9626448.html

5.靜態文件處理

https://blog.csdn.net/jj546630576/article/details/78606531

 https://note.qidong.name/2017/07/uwsgi-serve-django-static/

6.uwsgi啟動django

https://blog.csdn.net/weixin_43667990/article/details/99710786

https://www.jianshu.com/p/0e85cf58e677

https://www.cnblogs.com/wcwnina/p/9906081.html

https://blog.csdn.net/smart_liu8/article/details/82388930

https://blog.csdn.net/qq_34939371/article/details/102856541

7.nginx配置

https://www.cnblogs.com/wcwnina/p/9906081.html

https://www.cnblogs.com/suguangti/p/11334692.html

8.nginx概念與配置

https://www.jianshu.com/p/956debe2891d

 

 

如果覺得寫的還可以,請給個贊,多謝支持!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM