Nginx+Gunicorn+virtualenv+supervisord+Postgresql部署Django应用
时间:2022-03-10 17:38
关于Django应用部署
Django是一个高效、多功能和动态地进化的Web应用开发框架。目前比较流行的部署、运行Django应用方式是基于Apache的mod_wsgi模块,但更加高效、弹性,同时又更加复杂的方式是使用以下工具来部署实施:Nginx、Gunicorn、virtualenv、supervisord、Postgresql。以下详细介绍如何结合这些工具来部署Django应用到Linux上。
准备工作
需要有一台拥有root权限的Linux服务器,这是部署应用的平台。本文采用CentOS,域名直接使用localhost,ip地址为192.168.56.1。
使用yum在线升级机制来更新系统:
yum update -y
PostgreSQL
使用PostgreSQL来作为Django应用的后台数据库,在CentOS上安装:
yum install postgresql-contrib postgresql postgresql-server postgresql-devel
创建应用的数据库用户django和数据库hello_django:
su - postgres
createuser -P
Enter name of role to add: django
Enter password for new role:
Enter it again:
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles (y/n) n
createdb --owner django hello_django
logout
为应用添加系统用户
为Django应用创建专门的系统用户,并加入django_webapps群组:
groupadd django_webapps
useradd -g django_webapps -d /django_webapps/hello_django django
创建应用的Python虚拟环境
创建django_webapps目录来保存web apps,创建hello_django目录存储应用,并修改应用目录的拥有者:
mkdir -p /django_webapps/hello_django/
chown django /django_webapps/hello_django/
在应用目录创建虚拟环境,以django用户来创建:
su - django
cd /django_webapps/hello_django/
virtualenv .
激活虚拟环境:
source bin /activate
安装django:
pip install django
创建一个空的django项目,项目名为hello:
django-admin.py startproject hello
运行django自带的服务器来测试:
cd hello
python manage.py runserver localhost:8000
Validating models...
0 errors found
June 14, 2014 - 03:28:01
Django version 1.6.5, using settings ‘hello.settings‘
Starting development server at http://localhost:8000/
Quit the server with CONTROL-C.
登录 ,可查看到django的欢迎页面。
允许其他用户对应用目录写使能
应用是以django用户来运行的,该用户具有应用目录的所有权限。如果想让其他的常规用户也能够修改应用文件,那么可以设置群组users为该目录的群拥有者,并赋予users写权限:
chown -R django:users /django_webapps/hello_django
chmod -R g+w /django_webapps/hello_django
将django加入users群组中,并检查:
usermod -a -G users `whoami`
id
uid=507(django) gid=510(django_webapps) groups=510(django_webapps),100(users)
配置PostgreSQL
为了在Django中使用PostgrelSQL,需要安装psycopg2。在安装psycopg2之前需要安装python-devel,以保证能构建python模块:
yum install python-devel
在虚拟环境中使用pip安装psycopg2数据库适应器:
pip install psycopg2
修改settings.py文件来配置数据库:
DATABASES = {
‘default‘: {
‘ENGINE‘: ‘django.db.backends.postgresql_psycopg2‘,
‘NAME‘: ‘hello_django‘,
‘USER‘: ‘django‘,
‘PASSWORD‘: ‘131415‘, #此处最好使用密钥,可通过md5来加密
‘HOST‘: ‘localhost‘,
‘PORT‘: ‘‘, #set to empty string for default
}
}
最后构建Django的初始化数据库:
python manage.py syncdb
注解:构建过程中会出现error:IDENT authentication failed for user “django”
出现这个问题是因为PostgreSQL的Client Authentication 使用了ident authentication。
通过修改pg_hba.conf可以解决,编辑/var/lib/pgsql/data/pg_hba.conf,修改为:
# TYPE DATABASE USER CIDR-ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
Gunicorn
在生产环境中,我们将不会使用Django自带的单线程的开发服务器,而是使用专门的Python WSGI 应用服务器——gunicorn,在本博的另一篇文章中有对gunicorn的详细介绍:
首先在你的应用的虚拟环境中安装gunicorn:
pip install gunicorn
安装成功后可以测试下gunicorn是否可以运行Django 应用,在项目hello目录下运行以下命令:
(hello_django)[django@rango hello]$ gunicorn hello.wsgi:application --bind localhost:8001
通过访问 ,可以访问到你的Gunicorn服务器。此处特意将端口从8000改为8001是为了迫使浏览器建立一个新的连接。
Gunicorn现在已经准备好运行你的app,现在可以配置一些选项来使得Gunicorn更加有用。此处通过编写一个shell脚本来设置一些参数,脚本保存为/django_webapps/hello_django/bin/gunicorn_start:
#!/bin/bash
NAME="hello_app" # Name of the application
DJANGODIR=/django_webapps/hello_django/hello #Django project directory
SOCKFILE=/django_webapps/hello_django/run/gunicorn.sock #unix socket fro communication
USER=django # the user to run as
GROUP=django_webapps # the group to run as
NUM_WORKERS=5 # how many worker processes should Gunicorn spawn
DJANGO_SETTINGS_MODULE=hello.settings # which settings file should Django use
DJANGO_WSGI_MODULE=hello.wsgi # WSGI module name
echo "Starting $NAME as `whoami`"
# Activate the virtual environment
cd $DJANGODIR
source ../bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
# Create the run directory if it doesn‘t exist
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR
# Start your Django Unicorn
# Programs meant to be run under supervisor should not daemonize themselves (do not use --daemon)
exec ../bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $NUM_WORKERS \
--user=$USER --group=$GROUP \
--log-level=debug \
--bind=unix:$SOCKFILE
为该脚本增加可执行权限:
chmod u+x bin/gunicorn_start
以用户django的身份来运行这个脚本:
su - django
bin/gunicorn_start
Starting hello_app as django
2014-06-15 15:17:20 [18037] [INFO] Starting gunicorn 18.0
2014-06-15 15:17:20 [18037] [DEBUG] Arbiter booted
2014-06-15 15:17:20 [18037] [INFO] Listening at: unix:/django_webapps/hello_django/run/gunicorn.sock (18037)
2014-06-15 15:17:20 [18037] [INFO] Using worker: sync
2014-06-15 15:17:20 [18048] [INFO] Booting worker with pid: 18048
2014-06-15 15:17:20 [18049] [INFO] Booting worker with pid: 18049
2014-06-15 15:17:20 [18050] [INFO] Booting worker with pid: 18050
2014-06-15 15:17:20 [18051] [INFO] Booting worker with pid: 18051
2014-06-15 15:17:20 [18052] [INFO] Booting worker with pid: 18052
^C
2014-06-15 15:17:51 [18052] [INFO] Worker exiting (pid: 18052)
2014-06-15 15:17:51 [18051] [INFO] Worker exiting (pid: 18051)
2014-06-15 15:17:51 [18037] [INFO] Handling signal: int
2014-06-15 15:17:51 [18048] [INFO] Worker exiting (pid: 18048)
2014-06-15 15:17:51 [18049] [INFO] Worker exiting (pid: 18049)
2014-06-15 15:17:51 [18050] [INFO] Worker exiting (pid: 18050)
2014-06-15 15:17:51 [18037] [INFO] Shutting down: Master
注解:需要按照你自己的设置来修改脚本的路径和文件名。
‘"$http_user_agent" "$http_x_forwarded_for"‘;
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
# Nginx virtual server configuration for Django
upstream hello_app_server {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response (in case the Unicorn master nukes a
# single worker for timing out).
server unix:/django_webapps/hello_django/run/gunicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name localhost;
client_max_body_size 4G;
access_log /django_webapps/hello_django/logs/nginx-access.log;
error_log /django_webapps/hello_django/logs/nginx-error.log;
location /static/ {
alias /django_webapps/hello_django/static/;
}
location /media/ {
alias /django_webapps/hello_django/media/;
}
location / {
# an HTTP header important enough to have its own Wikipedia entry:
# http://en.wikipedia.org/wiki/X-Forwarded-For
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# enable this if and only if you use HTTPS, this helps Rack
# set the proper protocol for doing redirects:
# proxy_set_header X-Forwarded-Proto https;
# pass the Host: header from the client right along so redirects
# can be set properly within the Rack application
proxy_set_header Host $http_host;
# we don‘t want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
# set "proxy_buffering off" *only* for Rainbows! when doing
# Comet/long-poll stuff. It‘s also safe to set if you‘re
# using only serving fast clients with Unicorn + nginx.
# Otherwise you _want_ nginx to buffer responses to slow
# clients, really.
# proxy_buffering off;
# Try to serve static files from nginx, no point in making an
# *application* server like Unicorn/Rainbows! serve static files.
if (!-f $request_filename) {
proxy_pass http://hello_app_server;
break;
}
}
# Error pages
error_page 500 502 503 504 /500.html;
location = /500.html {
root /django_webapps/hello_django/static/;
}
}
# Load config files from the /etc/nginx/conf.d directory
# The default server is in conf.d/default.conf
include /etc/nginx/conf.d/*.conf;
}
注解:
# using only serving fast clients with Unicorn + nginx.
# Otherwise you _want_ nginx to buffer responses to slow
# clients, really.
# proxy_buffering off;
# Try to serve static files from nginx, no point in making an
# *application* server like Unicorn/Rainbows! serve static files.
if (!-f $request_filename) {
proxy_pass http://jay_app_server;
break;
}
}
# Error pages
error_page 500 502 503 504 /500.html;
location = /500.html {
root /django_webapps/jay_django/static/;
}
}
可以修改hello_app_server服务器的server_name为hello.sysu
保存配置文件并重启nginx:
service nginx restart
最后设置好域名,以便DNS服务器能够解析刚才设置好的两个域名:vim /etc/hosts
192.168.56.1 hello.sysu jaycn.sysu
通过登录每个域名来测试服务器上的app是否设置正确:
——游响云停
本文出自 “” 博客,请务必保留此出处
Nginx+Gunicorn+virtualenv+supervisord+Postgresql部署Django应用,布布扣,bubuko.com