部署实践:Django + virtualenv + gunicorn + Circus

题记

之前的实践中:DJANGO 部署:UBUNTU+NGINX+GUNICORN (超赞)

存在不少的问题,第一个是无法 gunicorn 无法设置随系统启动(很奇怪一直搞不了),第二个是进程挂了之后不会自己重启容易造成宕机。

另外,在此前的部署中没有使用 virtualenv 和用户之间进行切分,这样来说对于整个项目的重新部署来说其实缺少了很必要的指引。

因此,下面我们引入新的组件 virtualenv 和 circus,让我们的 django 应用更加稳定地运行。

下面假设已经对之前的纯 gunicorn 部署成功,可以单独运行 gunicorn 启动应用的前提下进行。


1. 添加 virtualenv

参考此文:【转】利用VIRTUALENV管理PYTHON环境

先通过下面的命令安装好 virtualenv 和 virtualenv-wrapper

sudo pip install virtualenv
sudo pip install virtualenvwrapper

1.1. 创建虚拟环境

一般而言我们会创建一个用户(其实也可以不用)来管理一个应用。

adduser djangouser

然后赋予其 sudo 权限:

visudo
# User privilege specification
root    ALL=(ALL:ALL) ALL
# 在这行后面加上:
djangouser    ALL=(ALL:ALL) ALL

然后我们 su 到这个 djangouser,并进入 django 的项目目录(即 manage.py 所在的目录)。

当然,一个可选的很好的方案就是,把 django 的项目目录放到 /home/djangouser/ 下面(这里我的项目放在了 /var/www/django/myproject)。

su djangouser
cd /var/www/django/myproject

1.2. 创建一个虚拟环境

mkvirtualenv django

注意,这样的话是会默认拿 python2 作为环境的,如果需要用 Python3,需要加上 -p 参数指定 python shell:

virtualenv -p /usr/bin/python3 django

然后我们就在这个 djangouser 的用户文件夹下面创建了一个虚拟环境。

日后需要进入这个虚拟环境,只需要:

workon django

相同类型的 django 项目可以共用一个虚拟环境,例如将同一个项目部署几个实例。

1.3. 安装依赖,创建 requirements.txt

因为我们在 virtualenv 里面需要重新安装所有的 PyPI 包,因此我们先在 manage.py 所在的目录下面创建 requirements.txt,下面举个例子,只是需要保证所有的 PyPI 依赖都被装上,以后的开发中,引入新的 PyPI 要及时更新到 requirements.txt 中:

gunicorn
django==1.8.1
pillow
chardet

然后通过这个 requirements.txt 更新实例:

pip install -r requirements.txt

1.4. 测试启动项目

测试虚拟环境的 django 启动
python manage.py runserver 0.0.0.0:8000

然后可以远程测试一下,成功之后说明虚拟环境运行良好。

测试 gunicorn 在虚拟环境下的启动
gunicorn --chdir /var/www/django/myproject myproject.wsgi

然后执行正确之后说明 OK 了。

2. 部署 Circus 进程守护

可以认为 Circus 自动帮你启动一个 gunicorn 进程,并且随时帮你盯着,如果进程死了,就自动重启进程。

2.1. 安装 Circus

pip2 install circus

然后编辑 /etc/init/circus.conf 文件

start on filesystem and net-device-up IFACE=lo
stop on runlevel [016]

respawn
exec /usr/local/bin/circusd /etc/circus.ini

然后就可以启动服务了。

sudo service circus start

2.2. 配置实例

在上面引用的配置文件 /etc/circus.ini 里面写入如下配置:

[circus]
check_delay = 5
endpoint = tcp://127.0.0.1:5555
pubsub_endpoint = tcp://127.0.0.1:5556
statsd = true

[watcher:myproject]
working_dir = /var/www/django/myproject
cmd = gunicorn
args = -w 1 -t 60 --pythonpath=. -b 127.0.0.1:8081 myproject.wsgi
uid = djangouser
numprocesses = 1
send_hup = true
autostart = true
stdout_stream.class = FileStream
stdout_stream.filename = /var/log/myproject.stdout.log
stdout_stream.max_bytes = 10485760
stdout_stream.backup_count = 4
stderr_stream.class = FileStream
stderr_stream.filename = /var/log/myproject.stderr.log
stderr_stream.max_bytes = 10485760
stderr_stream.backup_count = 4

[env:myproject]
PATH = /home/djangouser/.virtualenvs/django/bin:$PATH
TERM=rxvt-256color
SHELL=/bin/bash
USER=djangouser
LANG=en_US.UTF-8
HOME=/home/ecerp
PYTHONPATH=/home/djangouser/.virtualenvs/django/lib/python3.4/site-packages

说明一下:

[circus] 节不用管,有一个就够;

[watcher:myproject][env:myproject] 是关于这个 django 项目的;前者是跑 django 的,后面是设置运行的虚拟环境的。

如果需要添加其他的 gunicorn 实例,只需要按样子添加这两个节即可。

然后重启一下 circus,如无意外 wsgi 服务已经顺利跑起,剩下的只需要确保 nginx 配置对,就可以稳定高效的运行这个 django 应用了。


【转载请附】愿以此功德,回向 >>

原文链接:https://www.huangwenchao.com.cn/2015/05/django-virtualenv-gunicorn-circus.html【部署实践:Django + virtualenv + gunicorn + Circus】

《部署实践:Django + virtualenv + gunicorn + Circus》有2个想法

    1. 其实我也不太懂,我是在部署 Taiga 这个开源项目的时候,才发现的这个 Circus,以前是直接用 Gunicorn。然后后面我就依葫芦画瓢搞着搞着就可以用了,具体的配置方法其实我是一知半解。附 Taiga 项目的部署说明:taiga 安装过程

发表评论

电子邮件地址不会被公开。 必填项已用*标注