Nginx+uwsgi+virtualenv部署Django/Flask:以树莓派部署RewrZ为例子

发布于 2017-10-15  33 次阅读


我之前已经用Flask开发过一个博客,并且使用Nginx+uwsgi+virtualenv成功部署到树莓派上面,这次同样是使用树莓派作为上线测试用的服务器,将Django开发的RewrZ成功部署到上面,发现其实都是大同小异的,除了wsgi.py文件内容不一样之外,其他的配置内容几乎一致。所以就以RewrZ部署为例,探讨下这个组合的部署方式,因为其中涉及的坑其实特别多,并没有网上千篇一律的教程那样三言两语就能了事的,看似非常简单,实则根本就是个大坑。

前言

很多现成的教程看得超级难受,总是很多地方有坑都完全不说,很多地方搞不明白也没有解释提及,还要你另外到处去找教程,那些教程又惊人的相似,可参考价值太低太低。本篇文章可能还有很多不足之处,但一般部署,我想是完全足够了,我将自己部署过程中遇到的坑以及解决方案都一一记录下来,以后也会及时更新新的内容。

安装Python+Virtualenv+Nginx

可以的话不建议使用Virtualenv,这玩意无法 import sqlite3,试过很多方法都无法解决,直接安装在正式环境算了。

sudo apt-get install gcc # 安装GCC
sudo apt-get install python-pip python-dev python3-dev # 安装Python
sudo pip install virtualenv # 安装Virtualenv
sudo apt-get install nginx # 安装Nginx

Nginx安装失败处理

Nginx安装失败可能是因为apache2服务在运行。

whereis apache2 # 查看是否安装了apache2。
sudo service apache2 stop # 停止运行apache2
sudo apt-get install nginx # 安装Nginx

上传网站程序

创建存放网站的目录(如Django),把网站程序上传。
随便你喜欢上传到哪里,不赘述。

Virtualenv虚拟环境

cd django #进入网站目录(如django)
virtualenv .env # 创建虚拟环境(如在.env文件夹下)
virtualenv -p /usr/bin/python3 .env # 如果要指定python版本
source .env/bin/activate # 激活虚拟环境

其中,.env 为虚拟环境名称,可以根据自己喜欢随意更改。
退出虚拟环境命令:deactivate
删除虚拟环境命令是:rm -rf .env

安装Flask/Django、uwsgi

(激活虚拟环境后执行)

pip install django # 安装Django
pip install uwsgi # 安装uwsgi

网站程序初始化(以RewrZ为例)

(PS:虚拟环境内执行)

# 安装依赖
pip install -r requirements.txt
# 收集静态文件
python manage.py collectstatic
# 迁移数据库
python manage.py makemigrations
# 自动创建数据库
python manage.py migrate
# 创建超级管理员
python manage.py createsuperuser
# 建立索引文件
python manage.py rebuild_index

如果安装依赖出现失败,很可能是有其他关联的依赖库没安装:如libxslt1-dev(libxslt-dev)、libxml2-dev、libffi-dev等,执行sudo apt-get install进行安装之后再试。最常出现的是lxml安装出错,试了很多方法都无效,看到有个老外说是内存不足之类的也会编译失败。关了系统第二天一开机就安装,结果竟然成功了。

如果安装xml报错:

dpkg: error processing python-minimal (--configure)

进入超级管理员账户:

sudo -I

执行自动修复脚本:

for pkg in $(dpkg --get-selections | egrep -v 'deinstall' | egrep python | awk '{print $1}'); do  apt-get -y --force-yes install --reinstall $pkg ; done

退回普通用户

su pi # pi是我的树莓派默认用户名

配置uwsgi

增加配置文件uwsgi.ini,内容如下(RewrZ项目自带案例):

[uwsgi]
# 项目目录
chdir=/home/pi/Public/django/rewrz/
# 虚拟环境目录
virtualenv=/home/pi/Public/django/.env
home=/home/pi/Public/django/.env
module=rewrz.wsgi:application
# 配置自动reload无需手动重启
py-autoreload=1
# clear environment on exit
vacuum=true
master=true
# maximum number of worker processes
# 同一时间可以处理几个请求(32-100)
processes=32
# 进程数
workers=2
# 序列化接受的内容,如果可能的话
thunder-lock=true
# 启用线程
enable-threads=true
# 线程数
threads=10
# 设置自自杀时间
harakiri=60
# 设置缓冲
post-buffering=4096
# limit the project to 256 MB
limit-as = 256
socket=%(chdir)/rewrz.sock
chmod-socket=666
logfile-chmod=644
# 最大请求
max-requests=2000
# background the process & log
daemonize=%(chdir)/uwsgi.log
# create a pidfile
pidfile=/tmp/rewrz-master.pid
# 启动uwsgi的用户名和用户组
uid=pi
gid=pi
Procname-prefix-spaced=rewrz

目录路径请按照实际情况修改,pwd命令可查看当前目录的全路径。

启动uwsgi

uwsgi –i uwsgi.ini

成功将会出现提示:

[uWSGI] getting INI configuration from uwsgi.ini

启动:uwsgi --ini uwsgi.ini
停止:uwsgi --stop uwsgi.pid
重新加载:uwsgi --reload uwsgi.pid
uwsgi.pid为进程pid文件

配置Nginx

sudo rm /etc/nginx/sites-enabled/default # 删除Nginx默认配置文件
sudo nano /etc/nginx/sites-available/django.conf # 在/etc/nginx/sites-available目录下创建django.conf文件(名字随你喜欢) 

内容如下(RewrZ项目自带案例):

server {
	listen 80;
	server_name rewrz.com;
	charset utf-8;
	# max upload size
	client_max_body_size 50M;
	# 启用gzip压缩
	gzip on;
	# 压缩类型
    gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php application/json text/json image/jpeg image/gif image/png application/octet-stream;
	location / {
			include uwsgi_params;
			uwsgi_pass unix:/home/pi/Public/django/rewrz/rewrz.sock;
		}
	location /static {
		alias /home/pi/Public/django/rewrz/static; # your Django project's static files
	}
	location /media  {
        alias /home/pi/Public/django/rewrz/media;  # your Django project's media files
    }
}

为了使用这个配置文件生效,创建django.conf的链接文件:

sudo ln -s /etc/nginx/sites-available/django.conf /etc/nginx/conf.d/ # 创建软连接

重启Nginx

Nginx安装后默认就已经启动,修改了配置文件,需要对其进行重启。

重启前先对nginx配置进行语法检查

sudo nginx -t

正常情况会出现类似提示:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

直接重启命令:

sudo /etc/init.d/nginx restart

或者

sudo service nginx restart

可能会出现类似的错误信息:

nginx: [error] open() "/usr/local/nginx/logs/nginx.pid" failed (2: No such file or directory)

类似的解决方法:

sudo /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

访问网站

如果是本地局域网网站,所以可以通过修改hosts来直接访问。Windows编辑C:\Windows\System32\drivers\etc\hosts文件,增加一项,例如:

192.168.1.72 rewrz.com

192.168.1.72 是我的树莓派在本地局域网的地址,你可以直接在路由器后台里面看到。

打开浏览器,输入rewrz.com,回车,即可以看到输出结果。

如果是互联网网站,则设置域名A记录即可,这不在本文章讨论范围内,就不赘述了。

如果系统安装了Apache2很可能会失败,因为同一个端口只能一个程序监听。可以尝试卸载或停用。

但我尝试过网上提供的停用方法,没有效果。于是我选择了卸载:

sudo apt-get remove apache
sudo apt-get autoremove 
sudo find  /etc -name "*apache2*" -exec  rm -rf {} \;
sudo rm -rf /var/www

当然你也可以通过修改端口来实现。

可能会遇到的其他坑

来自 <https://coyotelin.blogspot.com/2017/03/nginx-uwsgi-django-3-q.html>

sqlite3
如果你的專案是使用sqlite3資料庫的話那你可能會在運行時發生下列錯誤:

ImportError: No module named _sqlite3

而很理所當然就會使用pip執行安裝,但是卻出現下列錯誤:

RuntimeError: Package 'sqlite3' must not be downloaded from pypi

這是因為sqlite3已經被包括在python3所以無法使用pip安裝,必須重新編譯安裝python

$ sudo apt-get install libsqlite3-dev
$ cd Python-3.6.1
$ sudo ./configure --enable-loadable-sqlite-extensions && sudo make install

pcre 在運行uwsgi指令時,log紀錄可能會出現下列警告

!!! no internal routing support, rebuild with pcre support !!!

為了解決這個問題我們必須安裝pcre並重新安裝uwsgi

$ sudo apt-get install libpcre3 libpcre3-dev
$ pip uninstall uwsgi
$ pip install uwsgi