zoukankan      html  css  js  c++  java
  • 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:Anacondalibssl.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

    如果觉得写的还可以,请给个赞,多谢支持!

  • 相关阅读:
    【纯水题】POJ 1852 Ants
    【树形DP】BZOJ 1131 Sta
    【不知道怎么分类】HDU
    【树形DP】CF 1293E Xenon's Attack on the Gangs
    【贪心算法】CF Emergency Evacuation
    【思维】UVA 11300 Spreading the Wealth
    【树形DP】NOI2003 逃学的小孩
    【树形DP】BZOJ 3829 Farmcraft
    【树形DP】JSOI BZOJ4472 salesman
    【迷宫问题】CodeForces 1292A A NEKO's Maze Game
  • 原文地址:https://www.cnblogs.com/liudinglong/p/12185180.html
Copyright © 2011-2022 走看看