Django 是最受欢迎的基于 Python 的 web 框架之一,也非常适合新手入门。虽然 Django 为我们提供了一个用于测试的轻量级 server,但这个 server 不能用于实际生产环境的部署。最早的 Django 的部署方法推荐的是 Apache+mod_wsgi。演化到现在,django 的部署方法也变得越来越弹性、有效,也更加的复杂了。在下面的教程中我们需要使用下面的这些工具:
- Nginx: Web 服务器
- Gunicorn: WSGI 服务器
- virtualenv: Python 虚拟环境工具
- supervisor: 进程监管工具
- PostgreSQL: 数据库(也可以使用 MariaDB)
1 前期准备
你需要一个你拥有 root 权限的 server。下面的教程是基于 Debian 7,所有相同的步骤对于 Ubuntu 和其他的基于 Debian 的发行版都是适用的。
1.1 更新系统
首先确保系统处于最新的状态
1 | sudo aptitude update |
如果是 Ubuntu 的话,使用 apt
1 | sudo apt update |
1.2 创建一个运行账户
为了避免万一 web 应用被攻击以后带来不受控制的后果,我们一般会单独为 web 应用创建一个权限受限的用户来运行这个 web 应用。例如我们这里为我们的 django 应用创建一个名为hello
的用户,并将其归入webapps
这个组。
1 | $ sudo groupadd --system webapps |
1.3 安装数据库(PostgreSQL)
为基于 Debian 的系统安装 PostgreSQL,你只需要运行下面这个命令:
1 | $ sudo aptitude install postgresql postgresql-contrib |
完成安装以后为我们的 django 应用创建一个用户和一个数据库
1 | $ sudo su - postgres |
当然你也可以选择其他数据库,例如 MariaDB。简单应用也可以使用 SQLite 数据库。
2 Python 运行环境(virtualenv)
Virtualenv 是一个 Python 虚拟环境管理的工具,所谓虚拟环境就是讲你 Web 应用所需要的 python 环境从系统的 python 环境中独立出来,这使得你可以在不同的应用中使用不同版本的第三方库。
用下面的命令来在 Debian 上安装 Virtualenv
1 | $ sudo aptitude install python-virtualenv |
2.1 准备虚拟环境
这里我将 django 应用放在了/webapps
这个路径下面,如果你偏好/var/www
, srv
或者其他的路径也可以。首先在这个目录下面创建/webapps/hello_django/
文件夹来存储应用,并将这个文件夹的 owner 设置为上面我们创建的运行账户hello
1 | $ sudo mkdir -p /webapps/hello_django/ |
切换到hello
用户并创建虚拟环境
1 | $ sudo su - hello |
要精确控制创建虚拟环境的版本,可是通过 -p
传递控制参数 1
virtualenv -p python3 env
这时虚拟环境中创建的是 Python 版本就是当前命令行环境下 python3
命令对应的 Python 版本。事实上你可以通过输入具体的 Python 命令绝对路径来指定以任意的 Python 安装版本创建虚拟环境。
现在虚拟环境就被激活了,我们可以将 django 安装到这个虚拟环境里面
1 | Downloading/unpacking django |
完成 django 的安装以后我们来创建一个空的 django 项目
1 | (hello_django)hello@django:~$ django-admin.py startproject hello |
你可以通过启动测试服务器来测试是否一切正常
1 | (hello_django)hello@django:~$ cd hello |
现在你可以通过http://example.com:8000来访问了。
在部署已有的 Django 项目时,我们可以通过
1 | pip freeze > requirements.txt |
输出项目的版本依赖,然后将 requirements.txt
文件上传到服务器上,在虚拟环境中运行
1 | pip install -r requirments.txt |
来安装所有依赖库。
2.2 配置数据库
Django 默认的新工程使用的是 SQLite3 作为数据库的,这个数据库的性能不足以支持生产环境下的数据库应用。我们这里采用 PostgreSQL 来做为我们的 Django 项目的数据库。为了让 Django 能够使用 PostgreSQL,我们需要将psycopg2
安装到虚拟环境。首先安装这个包的依赖项
1 | libpq-dev |
然后通过 pip 来安装的psycopg2
1 | (hello_django)hello@django:~$ pip install psycopg2 |
现在可以将 Django 的数据库设置修改为:
1 | DATABASES = { |
然后向向 Postgres 应用你的 Django 设置
1 | (hello_django)hello@django:~$ python manage.py migrate |
3 Gunicorn
在实际生产环境中我们不会使用 Django 的单线程开发服务器。这里我们使用Gunicorn. Gunicorn ('Green Unicorn') 是一个 UNIX 下的纯 Python WSGI 服务器。它没有其它依赖,容易安装和使用。
通过 pip 来安装 Gunicorn
1 | (hello_django)hello@django:~$ pip install gunicorn |
安装好以后你可以尝试用 Gunicorn 来运行 Django 了
1 | (hello_django)hello@django:~$ gunicorn hello.wsgi:application --bind example.com:8001 |
上面的命令是一个简单的测试,为了真正在生产环境下使用 Gunicorn,我们还需要增加一些配置。我们把这些配置文件写成一个 bash 脚本,保存为 bin/gunicorn_start
1 |
|
将这个文件改成可执行模式
1 | $ sudo chmod u+x bin/gunicorn_start |
下面你可以尝试运行这个脚本了
1 | $ sudo su - hello hello@django:~$ bin/gunicorn_start Starting hello_app as hello 2013-06-09 14:21:45 [10724] [INFO] Starting gunicorn 18.0 2013-06-09 14:21:45 [10724] [DEBUG] Arbiter booted 2013-06-09 14:21:45 [10724] [INFO] Listening at: unix:/webapps/hello_django/run/gunicorn.sock (10724) 2013-06-09 14:21:45 [10724] [INFO] Using worker: sync 2013-06-09 14:21:45 [10735] [INFO] Booting worker with pid: 10735 2013-06-09 14:21:45 [10736] [INFO] Booting worker with pid: 10736 2013-06-09 14:21:45 [10737] [INFO] Booting worker with pid: 10737 ^C (CONTROL-C to kill Gunicorn) 2013-06-09 14:21:48 [10736] [INFO] Worker exiting (pid: 10736) 2013-06-09 14:21:48 [10735] [INFO] Worker exiting (pid: 10735) 2013-06-09 14:21:48 [10724] [INFO] Handling signal: int 2013-06-09 14:21:48 [10737] [INFO] Worker exiting (pid: 10737) 2013-06-09 14:21:48 [10724] [INFO] Shutting down: Master $ exit |
注意,如果你在上面的过程中设置了自定义的参数的话,需要将gunicorn_start
脚本中对应的参数改过来。其中,worker 的数量推荐设置为 2 * CPUs + 1,这样的话,在任何时候都有一半的 worker 在做 IO。
4 Supervisor
Superviosr 是一个进程监管的工具。简而言之,Superviosr 可以保证你的程序在服务器开机时自动启动以及程序意外终止时重新启动。我们使用 Supervisor 来监管 Gunicorn 进程。
通过下面的命令即可安装:
1 | sudo aptitude install supervisor |
Superviosr 通过配置文件来设置被监管的程序。一般配置文件都放置在/etc/supervisor/conf.d
路径下面。此处我们创建一个名为hello.conf
的配置文件,内容如下:
1 | [program:hello] |
你可以参考其他设置,不过上面的设置一般情况下应该足够了。
日志文件需要我们手动创建一下:
1 | hello@django:~$ mkdir -p /webapps/hello_django/logs/ hello@django:~$ touch /webapps/hello_django/logs/gunicorn_supervisor.log |
设置好上面的文件以后,我们可以通过supervisorctl
工具来启用这些设置了:
1 | $ sudo supervisorctl reread |
现在你可以 start,stop 或者 restart 你的进程了
1 | $ sudo supervisorctl status hello hello RUNNING pid 18020, uptime 0:00:50 |
5 Nginx
安装 Nginx 同样非常简单:
1 | $ sudo aptitude install nginx |
此时你访问 server(http://example.com)就应该可以看见 Nginx 的欢迎页面了("Welcome to nginx")
5.1 为 Django 创建一个虚拟 server 配置
每个 Nginx 的虚拟 server 都由/etc/nginx/sites-available
路径下的一个配置文件来表示。而将其链接到的/etc/nginx/sites-enabled
路径下则可以启用对应的站点。
为我们的 Django 应用创建一个配置文件/etc/nginx/sites-available/hello
. 文件内容如下:
1 | upstream hello_app_server { |
将这个文件链接到site-enabled
文件夹下:
1 | $ sudo ln -s /etc/nginx/sites-available/hello /etc/nginx/sites-enabled/hello |
然后重启 nginx
1 | $ sudo service nginx restart |
现在你再访问http://example.com看到的就应该不是 nginx 的欢迎页面,而是 Django 的欢迎页面了。
至此配置就全部完成了,最终项目的整个结构应该如下所示:
1 | /webapps/hello_django/ |