本文由云+社区发表

本文主要讲述了如何一步步在生产环境上部署django和vue,操作系统默认为centos

说明:后文中出现的以下字符串均表示具体的路径或者名称,含义如下:

  • DJANGO_DIR----表示django的工程根目录
  • DJANGO_NAME----表示django的工程名称
  • VUE_HTML_DIR----表示vue编译好的index.html路径
  • VUE_STATIC_DIR----表示vue编译好的静态文件夹static的路径

整体框架

一个常用的web框架图如下图所示

框架选用.jpg

我们使用nginx + uwsgi来驱动django,因为uwsgi性能非常高

720333-20170312154455592-1425120615.png

一、安装和配置nginx

安装

使用yum安装即可

yum -y install nginx

启动

service nginx start

此时到浏览器输入对应的ip地址,出现下面页面即表示安装成功

1324702136-57fb16aa00d21_articlex.png

修改配置文件

nginx可以新建一个配置,放在项目目录,暂时不修改nginx的默认配置,端口号可以换一个,然后在/etc/nginx/conf.d/内新建一个软链接指向该配置文件,这样nginx在读取配置时会将该配置一起读进去。这样,访问端口号8080的请求便会指向我们自己的这个配置。

server {
listen 8080;
server_name 132.232.50.225;
root /data/;
charset utf-8;
access_log /data/access_narwhals.log;
error_log /data/error_narwhals.log;
client_max_body_size 75M;
location / {
uwsgi_pass 127.0.0.1:9090;
include /etc/nginx/uwsgi_params;
}
location ^~ /admin/ {
uwsgi_pass 127.0.0.1:9090;
include /etc/nginx/uwsgi_params;
}
}

该配置中uwsgi_pass要指向uwsgi绑定的接口。(我们先假设uwsgi配置的是9090端口)

二、安装和配置uwsgi

安装

使用yum或者pip均可安装

yum install uwsgi
# 或者
pip install uwsgi

不过这里需要注意,如果运行uwsgi出现下面错误

uwsgi: option '--http' is ambiguous; possibilities: '--http-socket' '--https-socket-modifier2' '--https-socket-modifier1' '--https-socket' '--http11-socket' '--http-socket-modifier2' '--http-socket-modifier1'
getopt_long() error

主要是用yum安装的uwsgi,缺少python的plugin,可以安装对应的插件

yum install uwsgi-plugin-python
plugins = python (加在ini配置文件中)

配置

uwsgi可以使用命令行启动,也可以使用配置文件来启动,推荐使用配置文件来启动守护进程,配置文件内容如下

[uwsgi]
socket = 127.0.0.1:9090
stats = 127.0.0.1:9293
workers = 4
# 项目根目录
chdir = DJANGO_DIR
touch-reload = DJANGO_DIR
py-auto-reload = 1
# 在项目跟目录和项目同名的文件夹里面的一个文件
module= DJANGO_NAME.wsgi
pidfile = /var/run/inner_manager.pid
daemonize = /data/uwsgi9090.log
# If you plan to receive big requests with lots of headers you can increase this value up to 64k (65535).
buffer-size=65535

这里以socket形式运行uwsgi,绑定了本地的9090端口,也就是上文nginx配置中uwsgi_pass指定的端口。

大概解释下几个配置的含义:

  1. chdir----应用加载前chdir到指定目录,一般设置为django的工程根目录
  2. touch-reload----如果修改/碰了指定的文件,那么重载uWSGI
  3. module----加载一个WSGI模块的路径,如果django的话就指向对应的wsgi文件模块
  4. buffer-size----设置请求的最大大小 (排除request-body),这一般映射到请求头的大小。默认情况下,它是4k。如果你接收到了一个更大的请求 (例如,带有大cookies或者查询字符串),那么你也许需要增加它。它也是一个安全度量,所以调整为你的应用需要,而不是最大输出。该值如果太小会报错

具体参数含义可以到官方文档查找

然后使用命令启动uwsgi进程,其中uwsgi.ini为上面内容的配置文件

uwsgi -i uwsgi.ini

可以看下日志文件有没有报错,或者看下ps -ef|grep uwsgi进程有没有跑起来。一定要确保进程正常run起来才行

至此,DJANGO已经通过nginx+uwsgi可以访问了

三、配置访问vue

其实这里访问编译好的vue静态文件有很多方式,本文主要讲述通过nginx直接访问通过django路由访问

通过django路由访问

其实我们也可以直接通过http://ip:8080/ 来经由django的路由来访问vue的页面。当然要做到这样要确保以下配置的正确

找到DJANGO_DIR根目录下DJANGO_NAME同名文件夹下urls.py,使用通用视图创建最简单的模板控制器,增加一行路由

url(r'^$', TemplateView.as_view(template_name="index.html")),

这样访问http://ip:8080/时会直接返回 index.html。

上一步使用了Django的模板系统,所以需要配置一下模板使Django知道从哪里找到index.html。在project目录的settings.py下:

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [VUE_HTML_DIR],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

按照上述配置完成后,结合前面配置好的nginx和uwsgi,你已经可以通过http://ip:8080/ 来访问到对应的vue编译好的VUE_HTML_DIR目录下的index.html了,但是这时候你可能会有其他困扰,比如找不到css样式文件的问,这经常是静态配置有误导致找不到静态文件的问题。

Django通过django.contrib.staticfiles来管理静态文件,首先确保django.contrib.staticfiles已经添加到INSTALLED_APPS。

然后可以在DJANGO的配置文件settings.py中增加以下几个配置:

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static")
# Add for vuejs
STATICFILES_DIRS = [
VUE_STATIC_DIR,
# other static folders
]
  • STATIC_URL对外提供WEB访问时static的URL地址
  • STATIC_ROOT设置绝对路径, 用来保存收集到的静态文件,服务器最终也将从该路径中获取文件进行转发。在collectstatic运行的时候会把STATICFILES_DIRS中的静态文件拷贝到这个目录中,达到从开发环境到生产环节过程中移植静态文件的作用。
  • STATICFILES_DIRS用来配置一些开发环境下生成的静态文件的地址,即编译好的VUE_STATIC_DIR

在url.py中添加路由

    url(r'^static/(?P<path>.*)$', static.serve,
{'document_root': settings.STATIC_ROOT}, name='static'),

配置好以上配置后,编译好的静态文件还在VUE_STATIC_DIR目录下,我们最终要执行下面命令才能把STATICFILES_DIRS中的静态文件拷贝到STATIC_ROOT这个目录中,也就是最终生产环境指定的static的存放目录

python manage.py collectstatic

那么为什么不直接手动把构建好的VUE_STATIC_DIR中的文件拷过来呢,因为Django自带的App:admin 也有一些静态文件(css,js等),它会一并collect过来,毕竟nginx只认项目跟目录的静态文件,它不知道django把它自己的需求文件放到哪了

这样你访问django的admin网址http://ip:8080/admin 时,也不会出现找不到css的问题了

当然这种方式其实是通过django的路由来访问静态文件的,一般的,生产环境不会通过django来转发静态文件,而是通过其他服务器进行转发,比如nginx,apache等,所以这里我们需要再配置下nginx的配置文件,在8080的server中增加如下路径的配置

   location /static/ {
expires 30d;
autoindex on;
add_header Cache-Control private;
alias VUE_STATIC_DIR;
access_log off;
}

这样访问静态文件便会直接通过nginx来访问了,不用担心静态文件访问导致Django的处理速度变慢了。

通过nginx直接访问

如果你想直接通过nginx访问对应的前端vue文件,可以重新配置一个server来访问对应的html文件,比如上面已经使用了8080端口,我们可以用默认的80端口来配置个server,其中root可以指向存放index.html文件的路径,/static/路径下的root路径可以指向html对应的存放css和js的static文件夹,如果static就在index.html路径下,不指认也可以。直接修改/etc/nginx.conf即可,里面已经有配置好的80端口的server

配置如下所示

    server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root VUE_HTML_DIR; # Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf; location / {
} location /static/ {
root VUE_STATIC_DIR;
access_log off;
} error_page 404 /404.html;
location = /40x.html {
} error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}

这样我们可以通过http://ip:80/ 来访问vue编译好的页面,使用http://ip:8080/ 访问django配置的cgi请求

四、通过supervisor管理进程

上面我们已经用到了uwsgi,后面可能还会用到redis、celery,都需要开启守护进程,其中celery自身还不支持守护进程。那么如何管理这么多进程呢,这时候可以考虑下supervisor

安装

使用pip安装即可

pip install supervisor

配置

我们可以配置redis,celery,uwsgi进去,比如向下面一样

[program:redis]
;指定运行目录
directory=%(here)s/
;执行命令(redis-server redis配置文件路径)
command=redis-server /etc/redis.conf ;启动设置
numprocs=1 ;进程数
autostart=true ;当supervisor启动时,程序将会自动启动
autorestart=true ;自动重启 ;停止信号
stopsignal=INT [program:celery.worker.default]
;指定运行目录
directory=%(here)s/
;运行目录下执行命令
command=celery -A DjangoProject worker --loglevel info --logfile log/celery_worker.log -Q default -n %%h-%(program_name)s-%(process_num)02d
process_name=%(process_num)02d ;启动设置
numprocs=2 ;进程数
autostart=true ;当supervisor启动时,程序将会自动启动
autorestart=true ;自动重启 ;停止信号,默认TERM
;中断:INT (类似于Ctrl+C)(kill -INT pid),退出后会将写文件或日志(推荐)
;终止:TERM (kill -TERM pid)
;挂起:HUP (kill -HUP pid),注意与Ctrl+Z/kill -stop pid不同
;从容停止:QUIT (kill -QUIT pid)
stopsignal=INT [program:uwsgi]
;指定运行目录
directory=%(here)s/
;运行目录下执行命令
command=uwsgi -i conf/uwsgi/uwsgi9090.ini ;启动设置
numprocs=1 ;进程数
autostart=true ;当supervisor启动时,程序将会自动启动
autorestart=true ;自动重启 ;停止信号,默认TERM
;中断:INT (类似于Ctrl+C)(kill -INT pid),退出后会将写文件或日志(推荐)
;终止:TERM (kill -TERM pid)
;挂起:HUP (kill -HUP pid),注意与Ctrl+Z/kill -stop pid不同
;从容停止:QUIT (kill -QUIT pid)
stopsignal=INT

使用

启动supervisor输入如下命令,使用具体的配置文件执行:

supervisord -c supervisord.conf

关闭supervisord需要通过supervisor的控制器:

supervisorctl -c supervisord.conf shutdown

重启supervisord也是通过supervisor的控制器:

supervisorctl -c supervisord.conf reload

一些特殊的变量

%(here)s   配置文件所在路径
(program_name)s program的名字
%(process_num)02d 多进程时的进程号

注意:command中如果含有%,需要进行转义%%

多进程时如果不指定process_name会遇到如下错误

Error: Format string 'celery -A INTProject worker --loglevel info --logfile log/celery_worker.log -Q diff_task,caller_task -n %h' for 'program:celery.worker.mac.command' is badly formatted: incomplete format in section 'program:celery.worker.mac' (file: 'supervisord.conf')

中间可能遇到的坑

*8107 recv() failed (104: Connection reset by peer) while reading response header from upstream, client 错误

使用django+uwsgi+nginx,发现如下报错

2018/10/08 14:34:33 [error] 12283#0: *8107 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 9.19.161.66, server: 132.232.50.225, request: "GET /auth/info?token=ZXlKaGJHY2lPaUprWldaaGRXeDBJaXdpZEhsd0lqb2lTbGRRSW4wOjFnOVA3aDp0bVZYcmg3XzJPR3RXSHJrbXFLRVdCZEpUdXc_ZXlKMWMyVnlibUZ0WlNJNkltVjBhR0Z1Wm1GdUlpd2lhV0YwSWpveE5UTTRPVGd3TkRjekxqZzVNekk1TVgwOjFnOVA3aDpMVXRHZkFiQkhrRTNaenFnS3NuS1RvOHBOMGM_3bdf34e6de16096f9982015a2382d3c8 HTTP/1.1", upstream: "uwsgi://127.0.0.1:9090", host: "int.oa.com", referrer: "http://int.oa.com/"

I finally found a reference to fastcgi and a 502 bad gateway error (https://support.plesk.com/hc/en-us/articles/213903705). That lead me to look for a buffer size limit in the uwsgi configuration which exists as buffer-size. The default value is 4096. From the documentation, it says: If you plan to receive big requests with lots of headers you can increase this value up to 64k (65535).

意思是uwsgi中有一项配置是buffer-size,表明收到的最大请求size,默认是4096,可以将其改成65535

buffer-size=65535

此文已由作者授权腾讯云+社区发布

如何一步步在生产环境上部署django和vue的更多相关文章

  1. hadoop进阶----hadoop经验(一)-----生产环境hadoop部署在超大内存服务器的虚拟机集群上vs几个内存较小的物理机

    生产环境 hadoop部署在超大内存服务器的虚拟机集群上 好 还是  几个内存较小的物理机上好? 虚拟机集群优点 虚拟化会带来一些其他方面的功能. 资源隔离.有些集群是专用的,比如给你三台设备只跑一个 ...

  2. django生产环境中部署

    https://www.cnblogs.com/chenice/p/6921727.html 本节内容 uwsgi 介绍 uwsgi安装使用 nginx安装配置 django with nginx 如 ...

  3. 数据仓库006 - MySQL 5.6.x - Linux最佳生产环境离线部署

    一.离线安装包 文件准备 这里以mysql-5.6.23-linux-glibc2.5-x86_64.tar.gz为例,记一次MySQL 5.6.x 的生产环境离线部署过程.使用SecureCRT连接 ...

  4. 生产环境Docker部署ELK跨区访问kafka不通问题的解决

    由于分布式系统的日志集中采集的需求非常强烈,我们组通过调研和实践搭建了一套基于Docker的日志收集系统Amethyst. 我们首先在测试环境搭建了一套基于Docker swarm集群的ELK分布式环 ...

  5. 生产环境上shell的解读

    一直以来对shell都不是很熟悉,只停留在基本的linux上操作上,这周因为定位问题接触到了生产环境上的脚本,因此作为引子学习一下.很多命令只是点到,等真正需要独立完成的时候再去学习. #!/bin/ ...

  6. Django + Uwsgi + Nginx 实现生产环境 项目部署

    内容: uwsgi 介绍 uwsgi安装使用 nginx安装配置 django with nginx 如何在生产上部署Django项目? Django项目的部署可以有很多方式,采用nginx+uwsg ...

  7. Tomcat学习总结(8)——Tomcat+Nginx集群解决均衡负载及生产环境热部署

    近日,为解决生产环境热部署问题,决定在服务器中增加一个tomcat组成集群,利用集群解决热部署问题. 这样既能解决高并发瓶颈问题,又能解决热部署(不影响用户使用的情况下平滑更新生产服务器)问题. 因为 ...

  8. CentOS上部署Django+Nginx+Uwsgi环境

    在CentOS上部署Django+Nginx+Uwsgi环境 奇谭  2016-09-01 评论  Linux  python django nginx uwsgi VirtualEnv的作用:创建隔 ...

  9. Linux生产环境上,最常用的一套“AWK“技巧【转】

    最有用系列: <Linux生产环境上,最常用的一套“vim“技巧> <Linux生产环境上,最常用的一套“Sed“技巧> <Linux生产环境上,最常用的一套“AWK“技 ...

随机推荐

  1. 学习笔记整理之StringBuffer与StringBulider的线程安全与线程不安全

    关于线程和线程不安全: 概述 编辑 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就 ...

  2. Hibernate框架:CRM练习--保存客户

    crm:customer ralation manager 客户关系管理系统 一.准备 1.创建web项目 2.导包 最终为: 3.引入静态页面 将文件复制放入项目的WebContent目录下面: 4 ...

  3. mac os ssh远程链接centos提示证书错误解决方法

    下面是错误提示 IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you ...

  4. 利用python list 完成最简单的DB连接池

    先来看查看效果: 在代码连接数据库后,并且执行三条sql后,将mysql直接重启掉,故我们的连接池连接均是不ok的,所以,它会全部删除再抓新的连接下来,重启mysql命令: 关于python代码: # ...

  5. Mac下git配置

    1.下载git 2.配置key macdeMacBook-Pro:~ mac$ cd ~/.ssh macdeMacBook-Pro:.ssh mac$ ssh-keygen -t rsa -C &q ...

  6. VS code的疑惑之处

    作为一个新手,我充满疑惑 eg:下载了git但无法使用匹配 然后在各位博主的详细解释下知道 VS code更新后的git.path被格式化了: so需要进行路径覆盖. 在这之后我的终端依旧出现问题   ...

  7. 了解AOP

    Spring AOP的实现是基于JAVA的代理机制, 从JDK1.3开始就支持代理功能, 但是性能成为一个很大问题, 为了解决JDK代理性能问题, 出现了CGLIB代理机制.它可以生成字节码, 所以它 ...

  8. linux根目录介绍

    1. /bin binary二进制 存放系统许多可执行程序文件 执行的相关指令,例如ls pwd whoami,后台的支持文件目录 2. /sbin super binary超级的二进制 存放系统许多 ...

  9. Bootstrap3.3.7

    页面的布局 <-!不让文字超出左右屏幕--> <style> .demo { word-wrap: break-word; } </style> 他们为那个模板中的 ...

  10. java实现中缀表达式转后缀表达式

    package postfix; import java.util.Stack; /** * * @author DELL 将中缀表达式转化为后缀表达式 */ public class Express ...