django+nginx+uwsgi项目部署

购买服务器

可以到阿里云,腾讯云,aws外国的服务器商购买服务器和域名;
其中各服务商有试用时间段,如果用于测试则可以使用免费的服务器。
大概步骤:

  1. 选择地区;
  2. 选择系统,一般为ubuntu16.04 x 64;
  3. 自己玩的话,最低配够了,视具体情况而定;
    4.买完之后会让你设置主机登录密码和远程密码;
    image.png

    购买成功之后,我们可以进入主机
    image.png

    输入在购买时所填的远程密码
    image.png

    连接之后输入主机用户(root)和密码(与上面远程密码不是同一个的,取决于你购买服务器时所填的)
    image.png

    然后升级环境
    apt update #新环境一般都更新下
  • 购买域名
    这个自己玩的可要可不要,域名要正常解析的话则国内需要备案,国外不需要


    image.png

    购买好域名备案之后,要将域名解析,绑定公网ip


    image.png

    各操作对应服务商会提供对应操作指引,按照其中执行即可。

python安装

一般linux服务器目前都安装python2.x版本,最新的都会装3.x的。可以查看系统中是否安装了python

#输入python即可查看相关信息
python2 --version #查看python2的版本信息
pyton3 --version #查看python3的版本信息

#如需要安装
sudo apt-get install python3.x   #安装python

Python3和Python2是互相不兼容,但也不能卸载python2,可以将Python的指向Python3,这样就可以默认使用python3了。

默认指向python2:
image.png

这里来改为指向python3
echo alias python=python3 >> ~/.bashrc
source ~/.bashrc   #source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。

再来看下,指向python3了:
image.png

需要用2则python2即可
image.png

安装pip3

查看pip是否安装
image.png

如出现以上界面,表示已安装pip了
但是需要注意是在哪个下面的,是python2还是python3下安装的


image.png

默认是装在python2下的
需要安装python3的:
apt install python3-pip   #主目录下,这可以可以全局使用pip3

注意

如果更新了pip
image.png

升级了pip,再次使用pip 安装相关的python包的时候就出现以下错误再来直接使用就会报错


image.png
ImportError: cannot import name main

解决:vim /usr/bin/pip3进去

from pip import main
if __name__ == '__main__':
    sys.exit(main())

换成下面即可:
from pip import __main__
if __name__ == '__main__':
    sys.exit(__main__._main())
image.png

安装虚拟环境

virtualenv可以搭建虚拟且独立的python运行环境, 使得单个项目的运行环境与其它项目独立起来,不与其他产生冲突,即安装在虚拟环境里的所有包,均不会对环境外的其他包产生影响,反之,在虚拟环境下运行时只能调用虚拟环境中安装的包,不会调用外部的包。相当于局部和全局之分;

  1. virtualenv本质上是个python包, 使用pip安装,选择建立虚拟环境的文件夹
pip3 install virtualenv        #安装虚拟环境     
  1. 使用virtualenv创建虚拟环境:
virtualenv  -p /usr/bin/python3 envpro    
# -p参数指定Python解释器程序路径,这将会使用 /usr/bin/python3 中的Python解释器。在当前目录下创建 envpro虚拟环境

envpro就是新建虚拟环境的目录。envpro下拥有bin、include、lib三个文件夹。本虚拟环境所有安装的Python库将存放在ENV/lib/pythonX.X/site-packages/下。 创建虚拟环境就会装好python,会将系统中的拷贝过来。

  1. 进入虚拟环境,注意:只有激活之后,才算进入该虚拟环境,否则安装包时,依然是安装在全局环境之下:
source envpro/bin/activate    #每次进入都要这样做,不能直接cd 这个目录进去

这种方式的虚拟环境配置简单,使用也很简单,但是需要记住虚拟环境的名字或者路径,鉴于virtualenv不便于对虚拟环境集中管理,所以推荐直接使用virtualenvwrapper。 virtualenvwrapper提供了一系列命令使得和虚拟环境工作变得便利。它把你所有的虚拟环境都放在一个地方。

virtualenvwrapper
#1.安装((确保virtualenv已安装):
pip3 install virtualenvwrapper
pip3 install virtualenvwrapper-win  #Windows使用该命令
#2.创建文件目录:
mkdir $HOME/.virtualenvs
#3.在.bashrc中(vim .bashrc)添加:
export WORKON_HOME=$HOME/.virtualenvs#virtualenvwrapper存放虚拟环境目录
source /usr/local/bin/virtualenvwrapper.sh 
#第二行:每次登陆用户自动执行下脚本,virtrualenvwrapper会安装到python的bin目录下,所以该路径是python安装目录下bin/virtualenvwrapper.sh,可用whereis virtualenvwrapper.sh查看virtualenvwrapper.sh的路径。
#4. 读入配置文件,立即生效
source ~/.bashrc

==> 报错:/usr/bin/python: No module named virtualenvwrapper

image.png
错误原因:错误原因:Ubuntu安装了2.7和3.x两个版本的python,在安装时使用的是sudo pip3 install virtualenvwrapper在我运行的时候默认使用的是python2.x,但在python2.x中不存在对应的模块。(virtualenvwrapper.sh文件内容如下:):
image.png

当不存在VIRTUALENVWRAPPER_PYTHON环境时,会默认选择使用which python(我这里默认是python2)
image.png

需要增加:export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
image.png

就可以重新激活成功:
image.png

继续完成后续配置

#5.创建虚拟环境 mkvirtualenv
#若想指定python版本,可通过"-p"指定python解释器
mkvirtualenv -p /usr/bin/python3 blogenv
#这样会在WORKON_HOME变量指定的目录下新建名为blogenv的虚拟环境。
#6.使用虚拟环境
进入:workon blogenv
退出:deactivate
#7.删除虚拟环境
rmvirtualenv blogenv
image.png
  1. 下载所需要的模块:
PS:python项目中必须包含一个 requirements.txt 文件,用于记录所有依赖包及其精确的版本号。其作用是用来在另一台PC上重新构建项目所需要的运行环境依赖,以便新环境部署。
# 在以前项目环境里导出环境
pip freeze > requirements.txt    #生成requirements.txt
# 在环境里安装相应的模块
pip install -r requirements.txt   #安装requirements.txt依赖,根据文件进行包安装,可以使用xftp软件把requitements.txt 文件放到传到服务器上,然后指定对应路径安装即可;
或者
一个一个安装项目中所需要的模块
安装Django    pip3 install django   
安装相应的模块 django-bootstrap4   django-simple-captcha 
django-ckeditor    django-pure-pagination   pymysql等等

退出虚拟环境:deactivate

安装数据库

  1. 安装 Mysql : sudo apt-get install mysql-server
    下载完之后进入安装,会提示输入root的密码qmpython
  2. 安装mysql:apt install libmysqlclient-dev
  3. 安装成功后可以通过下面的命令测试是否安装成功:
netstat -tap | grep mysql
  1. 设置mysql允许远程访问,首先编辑文件/etc/mysql/mysql.conf.d/mysqld.cnf
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf

注释掉bind-address = 127.0.0.1: #允许远程连接

保存退出(:x或者:wq)

然后进入mysql,mysql -u root -p

  1. 执行授权命令:
#创建普通用户:
create user 'username'@'%' IDENTIFIED BY 'password';  #qmpython
#"%",表示在任何一台电脑上都可以登录,也可以指定某台机器可以远程登录。
#给普通用户赋权
grant all on *.* to username@'%';
#如果要授予该用户对所有数据库和表的相应操作权限则可用*表示, 如*.*.

flush privileges;

然后执行quit命令退出mysql服务
  1. 配置完mysql之后需要重启mysql:
service mysql restart

Django项目部署

  • 此处从git直接clone下来方式部署
  1. 查看有没有git git --version 没有就安装 apt install git;

  2. 新建存放项目的文件夹/src/www

  3. 克隆自己的项目 git clone https://github.com/xx/xxx.git

  4. 修改设置 vim project/settings.py =>ALLOWDE_HOSTS =[“服务器ip”] ;

  5. 修改数据库对应配置;

  6. 迁移,进入项目目录下执行

python manage.py makemigrations
python manage.py migrate
createsuperuser
  1. python manage.py runserver 0:8000
  2. 浏览器打开ip或:8000
    如果打开正常则Django 部署成功
    注意:还可以通过pycharm连接阿里云服务器,然后根据同步代码功能同步过来或者XFTP同步文件过来。

uwsgi

  • WSGI
    Web Server Gateway Interface,WSGI不是服务器,python模块,框架,API或者任何软件,只是一种规范,描述web server如何与web application通信的规范。

  • uwsgi:与WSGI一样是一种通信协议,是uWSGI服务器的独占协议,用于定义传输信息的类型(type of information),与WSGI协议是两种东西。

  • uWSGI:是一个web服务器,实现了WSGI协议、uwsgi协议、http协议等。

  • 安装需要依赖的包

apt install python3-dev 
apt install gcc
  • 安装uwsgi
pip3 install uwsgi         #在虚拟环境里面,具体看实际
  • 测试uwsgi
    在虚拟环境中创建test.py文件
    image.png
#test.py
def application(env, start_response):
        start_response('200 OK', [('Content-Type','text/html')])
        return [b"hello world"]

运行uWSGI:

uwsgi --http :8000 --wsgi-file test.py
#http :8000:使用协议http,端口8000
#wsgi-file test.py:加载指定的文件test.py

这应该直接向端口8000上的浏览器发送“hello world”消息。访问:
http://www.qmpython.com:8000/ 结果:

image.png

如果要运行django项目则如下执行即可:

进入cd django项目中

uwsgi --http  :8000 --module  项目.wsgi         

浏览器输入ip:port即可查看测试结果
--卸载

pip3 uninstall uwsgi
sudo apt-get remove uwsgi

Nginx

Nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器;同时也是一个IMAP、POP3、SMTP代理服务器;Nginx可以作为一个HTTP服务器进行网站的发布处理,另外Nginx可以作为反向代理进行负载均衡的实现。Nginx就是性能非常好的反向代理服务器,用来做负载均衡。比如静态文件处理,安全,效率等等。

说到代理,首先我们要明确一个概念,所谓代理就是一个代表、一个渠道,我们先来了解正向代理和反向代理。

正向代理

我访问不了某网站比如www.google.com,但是我能访问一个代理服务器
这个代理服务器呢,它能访问那个我不能访问的网站,于是我先连上代理服务器,告诉它我需要那个无法访问网站的内容,代理服务器去取回来,然后返回给我。

image.png

正向代理的过程,隐藏了真实的请求客户端,服务端不知道真实的客户端是谁,客户端请求的服务都被代理服务器代替来请求。

反向代理

当我们请求 www.baidu.com 的时候,当我们访问www.baidu.com的时候,背后可能有成千上万台服务器为我们服务,但具体是哪一台,不知道,也不需要知道,只需要知道反向代理服务器是谁就好了,www.baidu.com 就是我们的反向代理服务器,反向代理服务器会帮我们把请求转发到真实的服务器那里去。

image.png

反向代理隐藏了真实的服务端。

负载均衡

我们已经了解了代理服务器的概念,Nginx扮演了反向代理服务器的角色,那它根据什么规则进行请求分发的?不用应用场景,分发规则是否可控呢?
这里提到的客户端发送的、Nginx反向代理服务器接收到的请求数量,就是我们说的负载量。
请求数量按照一定的规则进行分发到不同的服务器处理的规则,就是一种均衡规则。
所以~将服务器接收到的请求按照规则分发的过程,称为负载均衡。
负载均衡在实际项目中,有硬件负载均衡和软件负载均衡两种,硬件负载均衡也称为硬负载,如F5负载均衡,相对造价昂贵成本较高,但是数据的稳定性安全性等等有非常好的保障,如中国移动中国联通这样的公司才会选择硬负载进行操作;更多的公司考虑到成本原因,会选择使用软件负载均衡,软件负载均衡是利用现有的技术结合主机硬件实现的一种消息队列分发机制。

使用nginx

  • 安装nginx(在虚拟环境外执行)
apt install nginx  
  • 启动重启nginx
  /etc/init.d/nginx start(stop、restart)        
  • 测试nginx
nginx -t        #如果提示13: Permission denied则权限不够,用sudo nginx -t
#如果failed,则输入nginx -t查看错误信息,找到nginx.conf哪一行出错修改即可。

在浏览器输入ip地址,出现以下情况说明测试成功


image.png

PS:可以在浏览器中输入公网IP:端口,端口在阿里云安全组规则里面添加安全组规则端口,nginx默认只允许80,8000(可以通过文件配置,下面会提到)

nginx + uwsgi + django

先看下从网上找的图片


image.png

image.png

三者结合起来则需要修改几个配置文件:

uWSGI文件配置

/src/www/文件夹下建立两个文件qmblog_uwsgi.iniqmblog_uwsgi_params(这个.ini文件可以放在任何地方)

image.png

  • qmblog_uwsgi.ini文件
#配置域应该是uwsgi,记住这个不能丢,否则会报错
[uwsgi]
#uwsgi监听的socket,可以为socket文件或ip地址+端口号,用nginx的时候就配socket , 直接运行的时候配 http, http-socket = 127.0.0.1:8080
socket    = 127.0.0.1:8000

#指定项目的目录,在app加载前切换到当前目录
chdir           = /root/src/www/CainiaoBlog

# Django的wsgi文件,用来加载blog2/wsgi.py这个模块
module          =  CainiaoBlog.wsgi
# Python虚拟环境的路径
home            = /root/.virtualenvs/blogenv
# master 启动主进程。
master   = true
# 最大数量的工作进程数
processes   = 10
# 指定工作进程中的线程数
threads = 2

# 设置socket的权限
chmod-socket    = 664
# 退出的时候是否清理环境,自动移除unix Socket 和 Pid 文件
vacuum          = true
#日志文件路径
daemonize = /root/src/www/logback/uwsgi/blog_uwsgi.log
  • qmblog_uwsgi_params
uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;
    
uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUSET_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;
    
uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;
  • 启动
    进入qmblog_uwsgi.ini文件所在目录执行 uwsgi --ini qmblog_uwsgi.ini 或者在其他目录下执行要加载能访问此配置文件的路径如:uwsgi --ini /root/src/www/qmblog_uwsgi.ini,总而言之,记住一定要在uwsgi起作用的环境下,即在python对应虚拟环境下,且在能访问ini文件目录下执行;
  • 查看
  • 关闭
    sudo pkill -f uwsgi -9
nginx文件配置

/root/src/www目录下新建nginx.conf配置文件,内容如下:

#配置文件内容:
# 转发给哪个服务器,可以通过upstream配置项让nginx实现负载均衡
upstream django {    
    server   127.0.0.1:8000; 
    server   127.0.1.1:8000;
}

# 设定虚拟主机配置,一个http中可以有多个server。
server {
    # 启动的nginx进程监听请求的端口
    listen      80;
    #定义使用域名访问
    server_name  www.qmpython.com;  
    charset     utf-8;

    # max upload size  
    client_max_body_size 75M;    # adjust to taste

    # location 配置请求静态文件多媒体文件。
    location /media  {
        alias  /root/src/www/CainiaoBlog/media/;  
    }
    # 静态文件访问的url
    location /static {
        # 指定静态文件存放的目录
        alias /root/src/www/CainiaoBlog/static/;
    }

#  将所有非媒体请求转到Django服务器上
    location / {
        # 包含uwsgi的请求参数,路径为qmblog_uwsgi_params绝对路径
        include  /root/src/www/qmblog_uwsgi_params; 
        # 转交请求给uwsgi
        # uwsgi_pass  127.0.0.1:8000; 
        uwsgi_pass  django;  #这个django对应开头出的,对于动态请求,转发到本机的端口,也就是uwsgi监听的端口,uwsgi运行的主机和ip,后面我们会在本机的该端口上运行uwsgi进程
        # 下面两个配置意思是如果比如通过http://www.xxx.com直接访问的是static下的index.html或者index.htm页面,一般用于将首页静态化
        #root   /root/src/www/CainiaoBlog/static/;
        #index index.html index.htm; 
    }
    #精确匹配不同于上面/,这里http://www.xxx.com会匹配这个,根据这个配置将请求转发给另外nginx服务器,让另外服务器提供静态首页。同上面的访问index.html在另外同一台服务器上同一配置文件中结合。
   # location = / {
    #    proxy_pass  http://ip:port;
  #  }
}

注意:上面文件引用的路径需要能访问加载到,可以直接在当前路径下cd能进入相应目录下不;
然后进入

cd /etc/nginx/sites-enabled
rm default  #删除默认文件
ln -s /var/www/nginx.conf nginx.conf  #在此目录下创建软链接
  • 重启 nginx
  /etc/init.d/nginx start  (restart、stop)        
image.png
  • 关闭
  /etc/init.d/nginx stop
  • 注意:django Nginx设置静态资源,出现403 Forbidden

    如果出现静态文件访问资源403权限问题
    image.png

    需要查看主配置文件/etc/nginx/nginx.conf
    image.png

    这个www-data用户不存在,默认安装nginx给的是这个用户,但是程序所属的用户不是它,www-data这个默认的用户,没有静态文件的权限,所以报了个403,没权限,需要改成对应用户即可。


    image.png

加载/etc/nginx/nginx.conf主配置文件,然后加载前面在sites-enabled中创建的一软链接指向的文件,即我们前面改的配置文件。

开机自动启动 uwsgi 文件

which uwsgi 查看在命令在哪个路径下的(/usr/local/bin/uwsgi)
vim /etc/rc.local
在exit 0 前加一行

/etc/init.d/nginx start   #开机自动启动nginx
/src/www/blogenv/bin/uwsgi --ini /var/www/uwsgi.ini --chmod-socket=666 

然后reboot

静态文件处理

1.将settings.py配置文件中DEBUG = False
说明:
1)测试环境中打开调试模式,能够显示详细的报错信息,生产环境改为False避免暴露项目内部信息;
2)生产环境下,即关闭debug后django 不会从 static 目录读取静态文件,静态文件交由nginx去处理;
2.修改ALLOWED_HOSTS =["*"], “*”表示的就是任意的ip地址,生产部署为了防范攻击,改成本机ip地址和域名;

在pip安装模块的时候可能是连接的官网速度比较慢,可以使用豆瓣源
https://pypi.doubanio.com/simple/pip
如:
install xxx -i http://pypi.douban.com/simple/

本人个人博客:www.qmpython.com,就是通过以上方式搭建的。

欢迎关注微信公众号,一起学习交流

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容