还记得去年做实验室官网的后台的时候,代码写好了,就差部署了。
网上找了很多教程,最后还是失败了,直接就 runserver 裸奔的。
今年又去看了自强学堂涂伟忠老师的教程,感觉虽然很详细,但是比较复杂,并且环境有点不兼容,因为今年我是用的Python3写的了。所以就换了个。
找了很久找到了一个比较简洁但是好用的教程: Django + Uwsgi + Nginx 的生产环境部署
我基本上照着这个教程走,大部分操作可以完成,不过也遇到了一些比较奇怪的问题和一些操作问题:
首先需要注意的问题是,我们操作的目录,应该是在你的manage.py的同级目录。
其次需要注意的问题是命令和配置里面的路径设置,一定要和你的项目路径匹配,否则会发生很多很奇怪的错误的。
-
运行uwsgi提示no app found
运行这条命令之后出现了该问题,并且访问服务器的8080端口也打不开。
uwsgi --http 0.0.0.0:8080 --file teacher/wsgi.py
经过大量的检查,发现是我本地上传的代码,环境和服务器不一致。比如本地用了MySQLdb这个库,服务器并没有安装,仔细看报错信息也确实发现了报了这个错。于是就把服务器上没有的库都装上了,于是问题成功解决。
-
运行Nginx:access_log main 这一行报错
排查了问题,发现是作者把access_log放进了server的设置里面,所以报错了,于是把access_log拿出来了,报错charset=utf-8。然后按照新的教程添加了gzip支持。 -
gzip重复开启
在设置里面我只开了一个gzip on
的命令我查看conf.d目录下,就我这一个设置文件,感到了困惑,然后又百度之,发现在/etc/nginx/目录下有个nginx.conf文件,打开查看了,里面果然开启了gzip。所以我把我的设置里面的gzip on删了。 -
重启uwsgi命令不会用
uwsgi --ini uwsgi.ini # 启动
uwsgi --reload uwsgi.pid # 重启
uwsgi --stop uwsgi.pid # 关闭
uwsgi.pid和uwsgi.ini的位置都在我们的uwsgi.ini里面设置了。所以直接找到这uwsgi.pid文件,然后敲命令回车应该就可以了。但是报错了,路径出问题了,因为uwsgi.ini是在project/script/目录下的,我们重载的时候,也应该到manage.py的目录重启,否则配置文件里面的路径就会出错。所以重启应该改成uwsgi --reload ./script/uwsgi.pid
。
-
重启Nginx
我凭感觉,用了nginx restart
,不行。于是查资料:正确的应该是service nginx restart
。 -
用ip访问和用网址访问结果不一样
我终于配置好了Nginx和uwsgi。我用IP访问我的服务器的时候,看得到Nginx的服务页面,但是其他所有页面都是404,但是我通过网址访问的时候,又是正常的。这个操作也是Nginx的一个优点,同一个端口,可以区分来源是哪里的,然后分别转发到不同的端口。具体设置是在server{server_name www.xxx.com ...}
这里,如果server_name是ip,那么也不能通过网址正常访问了。
学习了“一年”的配置的一点总结
之前一直不知道uwsgi和Nginx是怎么发生关系的,看过博客之后,稍微多了一丝了解:
-
uwsgi是用来启动Django项目的。也就是我们不需要敲
python manage.py runserver 8000
,而是直接到uwsgi.ini里面配置好,直接使用uwsgi运行就好了,运行成功的话,我们就可以看到网站在127.0.0.1:8000成功运行了,如果需要外网访问的,就把IP设置成0.0.0.0,这样所有的IP都可以访问网站了,不止是本机。 -
Nginx是用来做请求转发与静态文件处理的。请求转发的情况是这样的,为了安全起见(也许不是),我们限制uwsgi的应用只能在本机跑,那么除了本机,没有任何人能够访问到网站。要让别人也访问,就只有开放另一个端口出来,用来接收到外界来的请求,然后转发到127.0.0.1:8000端口我们的网站上,这样uwsgi就成功接收到了外界的请求了。Nginx就是个中间人,把外界的请求转发进来,把内部请求返回回去。它既然承接了所有的请求,那么他就可以做一些多的事情了,比如压缩请求的内容(gzip),限制访问的频率,把静态文件(css/js/图片/视频/文件)直接返回回去,而不用经过网站请求的验证,Nginx的强大之处就在于对静态文件的处理。
-
Nginx到底是怎么和uwsgi发生关系的?通过uwsgi产生的sock文件。通过这个文件,Nginx知道了uwsgi的端口等信息,然后就自动配置了。在server里面配置uwsgi的sock 文件的目录,使用绝对路径。
uwsgi和Nginx,特别是Nginx,是一门高深的学问,它的设置项是真的多。。。
附上我的uwsgi.ini和mynginx.conf设置文件内容:
uwsgi.ini:
# uwsig使用配置文件启动
[uwsgi]
# 项目目录
chdir=/data/office/office1/
# 指定项目的application
module=office1.wsgi:application
# 指定sock的文件路径
socket=/data/office/office1/script/uwsgi.sock
# 进程个数
workers=5
pidfile=/data/office/office1/script/uwsgi.pid
# 指定IP端口
http=0.0.0.0:8080
# 指定静态文件
# static-map=/static=/opt/proj/teacher/static
# 启动uwsgi的用户名和用户组
uid=root
gid=root
# 启用主进程
master=true
# 自动移除unix Socket和pid文件当服务停止的时候
vacuum=true
# 序列化接受的内容,如果可能的话
thunder-lock=true
# 启用线程
enable-threads=true
# 设置自中断时间
harakiri=30
# 设置缓冲
post-buffering=4096
# 设置日志目录
daemonize=/data/office/office1/script/uwsgi.log
我的项目名叫office1,位于/data/office/目录下。所以配置文件首先就chdir,打开了我的manage.py的的目录,然后第二个设置才能起作用,找到application的位置。在manage.py同级目录创建了script文件夹之后,把uwsgi的ini,pid,sock文件都放在了script文件夹里面。
mynginx.conf
# $gzip_ratio计算请求的压缩率,$body_bytes_sent请求体大小
log_format main '$remote_addr - $remote_user [$time_local] "$host" - "$request" '
'$gzip_ratio - $body_bytes_sent - $request_time';
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# gzip 压缩级别,1-9,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明
gzip_comp_level 1;
# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 禁用IE 6 gzip
gzip_disable "MSIE [1-6]\.";
# 设置压缩所需要的缓冲区大小
gzip_buffers 32 4k;
# 设置gzip压缩针对的HTTP协议版本
gzip_http_version 1.0;
charset utf-8; # Nginx编码
server { # 这个server标识我要配置了
listen 80; # 我要监听那个端口
server_name www.yoururl.com; # 你访问的路径前面的url名称
# error_page 404 /404.html; # 错误页面
# error_page 500 502 503 504 /50x.html; # 错误页面
# 指定项目路径uwsgi
location / { # 这个location就和咱们Django的url(r'^admin/', admin.site.urls),
include uwsgi_params; # 导入一个Nginx模块他是用来和uWSGI进行通讯的
uwsgi_connect_timeout 30; # 设置连接uWSGI超时时间
uwsgi_pass unix:/data/office/office1/script/uwsgi.sock; # 指定uwsgi的sock文件所有动态请求就会直接丢给他
}
# 指定静态文件路径
location /static/ {
alias /data/office/office1/static/;
index /data/office/office1/templates/index.html; # 配置两个index.html也只认第一个
}
}
配置完成了之后,重启Nginx就OK了。
网友评论