django+ubuntu+uwsgi+nginx+supervisor+nohup项目部署

项目环境:python2.7, django1.9, ubuntu(阿里云服务器)

1.利用scp将项目传上阿里云服务器,运行开发服务器测试

(下面的项目名我都用projectname表示)运行命令:

        cd projectname # 进入项目projectname目录

        python manage.py runserver 0.0.0.0:8000

(运行开发服务器测试,确保开发服务器能正常打开网站)

这里有一个简易的办法让项目一直在后台运行:nohup,进入项目目录下运行命令:

        nuhup python manage.py runserver 0.0.0.0:8000&

在当前目录下会生成一个nohup.out文件,项目的输出信息全在里面,错误信息可从里面查找。但这不叫部署,下面开始部署。

2. 安装nginx 和需要的包

2.1 安装 nginx 等软件

        ubuntu / Linux Mint 等,下面简写为 (ubuntu):

        sudoapt-get install python-dev nginx

2.2 安装 supervisor, 一个专门用来管理进程的工具,我们用它来管理 uwsgi 进程

        sudopip install supervisor

在这有一个问题需要注意一下的就是,如果你是centOS用户,不是则直接进入3,请先查看一下你的seLinux是否开启,因为其存在安全性问题,会导致后面你利用nginx做反向代理你的项目时访问被拒绝。运行命令,将 SELinux 设置为宽容模式,方便调试:

        sudo setenforce 0

防火墙相关的设置:

可以选择临时关闭防火墙

        sudo service iptables stop

或者开放一些需要的端口,比如 8002

        sudo iptables -A INPUT -p tcp -m tcp --dport 8002 -j ACCEPT

上面的两条命令,如果是 CentOS用户用

临时关闭防火墙

        sudo systemctl stop firewalld

或者 开放需要的端口

        sudo firewall-cmd --zone=public --add-port=80/tcp--permanent

        sudo firewall-cmd --reload

3.使用uwsgi来部署

安装uwsgi

        sudo pip install uwsgi --upgrade

使用uwsgi 运行项目(我的项目放在/root下)

        uwsgi --http :8002 --chidir /root/projectname --home=/path/to/venv --module project.wsgi

这样就可以跑了,--home 指定virtualenv 路径,如果没有可以去掉。project.wsgi 指的是 project/wsgi.py 文件.

如果想安装virtualenv可以按下面步骤安装,不想则略过直接到4:

为什么要安装virtualenv?答案来自”廖雪峰python“(在开发Python应用程序的时候,系统安装的Python3只有一个版本:3.4。所有第三方的包都会被pip安装到Python3的site-packages目录下。如果我们要同时开发多个应用程序,那这些应用程序都会共用一个Python,就是安装在系统的Python 3。如果应用A需要jinja 2.7,而应用B需要jinja 2.6怎么办?这种情况下,每个应用可能需要各自拥有一套“独立”的Python运行环境。virtualenv就是用来为一个应用创建一套“隔离”的Python运行环境。)

下面开始安装:

        pip install virtualenv

然后,假定我们要开发一个新的项目,需要一套独立的Python运行环境,可以这么做:

第一步,创建目录:

        mkdir myproject

        cd myproject

第二步,创建一个独立的Python运行环境,命名为venv:

        virtualenv --no-site-packages venv

命令virtualenv就可以创建一个独立的Python运行环境,我们还加上了参数--no-site-packages,这样,已经安装到系统Python环境中的所有第三方包都不会复制过来,这样,我们就得到了一个不带任何第三方包的“干净”的Python运行环境。

建的Python环境被放到当前目录下的venv目录。有了venv这个Python环境,可以用source进入该环境:

        source venv/bin/activate

注意到命令提示符变了,有个(venv)前缀,表示当前环境是一个名为venv的Python环境。下面你就可以正常安装各种你想要的第三方包,运行python命令

在venv环境下,用pip安装的包都被安装到venv这个环境下,系统Python环境不受任何影响。也就是说,venv环境是专门针对myproject这个应用创建的。

退出当前的venv环境,使用deactivate命令:

        deactivate

此时就回到了正常的环境,现在pip或python均是在系统Python环境下执行。

3.1 查询端口

如果在3中出现端口被占的情况,通过命令查询端口:

        lsof -i:8002

再利用查询到的pid,通过kill命令关掉相关程序:

        kill -9 pid

或者按程序名称查询:以下两个命令都一样的效果,只是显示略有区别:

        ps -ef | grep uwsgi

        ps aux | grep uwsgi

4.使用supervisor来管理进程

安装 supervisor 软件包

        (sudo) pip install supervisor

生成 supervisor 默认配置文件,比如我们放在 /etc/supervisord.conf 路径中:

        (sudo) echo_supervisord_conf > /etc/supervisord.conf        

打开 supervisord.conf 在最底部添加(每一行前面不要有空格,防止报错):

        [program:projectname]        

        command=/path/to/uwsgi --http :8002 --chdir /path/to/projectname --module projectname.wsgi

        directory=/path/to/projectname

        startsecs=0

        stopwaitsecs=0

        autostart=true

        autorestart=true

command 中写上对应的命令,这样,就可以用 supervisor 来管理了。

启动 supervisor:

        (sudo) supervisord -c /etc/supervisord.conf        

重启 projectname 程序(项目):

        (sudo) supervisorctl -c /etc/supervisord.conf restart projectname

启动,停止,或重启 supervisor 管理的某个程序 或 所有程序:

        (sudo) supervisorctl -c /etc/supervisord.conf [start|stop|restart] [program-name|all]

以 uwsgi 为例,上面这样使用一行命令太长了,我们使用 ini 配置文件来搞定,比如项目在 /root/projectname 这个位置,

在其中新建一个 uwsgi.ini 全路径为 /root/projectname/uwsgi.ini

        [uwsgi]        

        socket = /root/projectname/projectname.sock

        chdir =/root/projectname

        wsgi-file= projectname/wsgi.py

        touch-reload =  /root/projectname/reload

        processes = 2

        threads = 4

        chmod-socket = 666

        chown-socket =www-data:www-data

        vacuum = true

在这有几个要注意的问题:

        (1)./root/projectname/projectname.sock ,待会配置nginx时我们把它和nginx关联起来,在这我们采用的sock方式通信,也可以直接采用ip地址加端口的形式,比如socket=127.0.0.1:8003,则后面配置nginx的时候也要写成一样的就行。

        (2).chmod-socket = 666 ,chown-socket =www-data:www-data有些人在后面可能会出现权限问题,所以在这直接设好,还有chown-socket设置,也就是gid,uid设置

        (3).不建议把 sock 文件放在 /tmp 下,比如 /tmp/xxx.sock (不建议)!有些系统的临时文件是 namespaced 的,进程只能看到自己的临时文件,导致 nginx 找不到 uwsgi 的 socket 文件,访问时显示502,nginx 的 access log 中显示 unix: /tmp/xxx.sock failed (2: No such file or directory),所以部署的时候建议用其它目录来放 socket 文件,比如放在运行nginx用户目录中,也可以专门弄一个目录来存放 sock 文件,比如 /tmp2/

        sudomkdir-p /tmp2/&& sudochmod777 /tmp2/

然后可以用 /tmp2/projectname.sock 这样的路径了。

修改 supervisor 配置文件中的 command 一行:

        [program:projectname]

        command=/path/to/uwsgi --ini /root/projectname/uwsgi.ini

        directory=/root/projectname(我的项目是放在/root下,你们按照你们的即可)

        startsecs=0    

5.配置 Nginx

在nginx下新建一个自己的项目projectname

        sudo vim /etc/nginx/sites-available/projectname.conf

写入以下内容:

        server {

            listen      8002;

            server_name localhost;         #有域名写域名,没域名写localhost或者" _" 或者公网ip

            charset     utf-8;

            client_max_body_size 75M;

            location /media  {

                alias /path/to/project/media;

            }

            location /static {

                alias /path/to/project/static;

            }

            location / {

                uwsgi_pass  unix:///root/peojectname/projectname.sock;

                include     /etc/nginx/uwsgi_params;

            }

        }

激活项目:

        sudo ln -s /etc/nginx/sites-available/projectname.conf /etc/nginx/sites-enabled/projectname.conf

测试配置语法问题:

        sudo service nginx configtest

如果显示fail,则通过下面命令查看具体原因:

        sudo nginx -t

重启 nginx 服务器:

        sudo service nginx reload 或 sudo service nginx restart 或 /path/to/nginx -s reload   

如果启动成功,则说明目前配置没有问题,如果启动失败,则应该是nginx配置没配好。

6.总结:

我在配置的时候出现的很多问题现总结如下:

 (1)nginx配置之后测试成功,但启动失败,当时配置的时候我发现是/etc/nginx/nginx.conf 文件被我不知道怎么给修改了,导致出现server not allow here.是因为nginx读取了/etc/nginx/sites-available/projectname.conf里面的配置,而这里面又没有http。projectname.conf这个文件应该是include在/etc/nginx/nginx.conf 文件里面的,修改回来之后则nginx启动成功。

(2)nginx启动成功了,但是没有成功代理项目,我用superivsorctl启动项目之后发现可以直接通过8002端口访问项目,nginx监听8002端口启动失败,查看原因发现地址被占,停止supervisorctl之后8002端口被放出,我在/etc/supervisord.conf和uwsgi.ini中均未指定端口,原因可能是superivsorctl在启动时启动了我其他时候配置过的项目或者运行了我之前利用uwsgi测试项目的命令,导致端口被占用。此时我考虑换一个端口8003,启动成功,但访问页面时失败。

分析是uwsgi.ini配置了端口还是superivsorctl配置了端口,我先单独运行uwsgi --ini uwsgi.ini 发现成功运行且未占用端口,显然是因为运行superivsorctl占用了端口。

(3)基于此考虑暂时放弃supervisor, 考虑先利用uwsgi --ini uwsgi.ini 命令在前台运行,端口未被占,nginx监听8002端口,启动成功,访问页面出现502,查看错误日志/var/log/nginx/error.log,发现是(13,permission deny),

a.查看网上资料发现很多人因为用的是centOS系统,出现seLinux安全性问题,一般解决方案关掉就行,上面我已经写了,

b.第二种情况是说权限问题,将chmod-socket = 666 ,chown-socket =www-data:www-data设置成这个,这里有一个问题就是,因为我是采用sock通信,启动uwsgi自动生成.sock文件,虽然我修改了权限,你会发现生成的sock文件权限并没有变化,这时你应该删除现在的sock文件,重新启动uwsgi,然后在启动nginx,看看你们有没有解决问题,

c.但我仍然没有解决问题,最后原因发现了是因为我用root身份运行的uwsgi,在/etc/nginx/nginx.conf里面的用户却是www-data,将其改成root之后,成功访问。

(4)之前我用uwsgi在前台通过设置http端口命令运行项目的时候发现static静态资源文件加载不出来,那是因为uwsgi没有理会静态资源文件,通过nginx反向代理之后,静态资源文件成功加载。

(5)还有一个问题没有解决就是,我的uwsgi是在前台运行的,supervisor又会出现莫名奇妙的8002端口占用,查看uwsgi进行发现有很多个进程在运行,这里考虑使用nohup 将uwsgi在后台运行,命令:

        nohup uwsgi --ini uwsgi.ini&

重启nginx:

        sudo service nginx restart

成功实现代理。

后期继续研究这个supervisor占用我8002端口的问题,从性能上利用supervisor管理uwsgi肯定比nohup更好。

你可能感兴趣的:(django+ubuntu+uwsgi+nginx+supervisor+nohup项目部署)