本文由云+社区发表css
本文主要讲述了如何一步步在生产环境上部署django和vue,操做系统默认为centoshtml
说明:后文中出现的如下字符串均表示具体的路径或者名称,含义以下:前端
一个经常使用的web框架图以下图所示vue
框架选用.jpgpython
咱们使用nginx + uwsgi来驱动django,由于uwsgi性能很是高nginx
720333-20170312154455592-1425120615.pngweb
使用yum安装便可redis
yum -y install nginx
启动apache
service nginx start
此时到浏览器输入对应的ip地址,出现下面页面即表示安装成功django
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端口)
使用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指定的端口。
大概解释下几个配置的含义:
具体参数含义能够到官方文档查找
而后使用命令启动uwsgi进程,其中uwsgi.ini为上面内容的配置文件
uwsgi -i uwsgi.ini
能够看下日志文件有没有报错,或者看下ps -ef|grep uwsgi
进程有没有跑起来。必定要确保进程正常run起来才行
至此,DJANGO已经经过nginx+uwsgi能够访问了
其实这里访问编译好的vue静态文件有不少方式,本文主要讲述经过nginx直接访问和经过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访问对应的前端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请求
上面咱们已经用到了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')
使用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
此文已由做者受权腾讯云+社区发布