Aunque Django bajo Apache y mod_python es la configuración más robusta de implementación, mucha gente usa hosting compartido, en los que FastCGI es la única opción de implementación.
Adicionalmente, en algunas situaciones, FastCGI permite mayor seguridad y posiblemente un mejor rendimiento que mod_python. Para sitios pequeños, FastCGI además puede ser más liviano que Apache.
20.4.1. Descripción de FastCGI
FastCGI es una manera eficiente de dejar que una aplicación externa genere páginas para un servidor Web. El servidor delega las peticiones Web entrantes ( a través de un socket) a FastCGI, quien ejecuta el código y devuelve la respuesta al servidor, quien, a su turno, la remitirá al navegador del cliente.
Como mod_python, FastCGI permite que el código permanezca en memoria, logrando que las peticiones sean servidas sin tiempo de inicialización. A diferencia de mod_python, un proceso FastCGI no corre dentro del proceso del servidor Web, sino en un proceso separado y persistente.
Antes de que puedas empezar a usar FastCGI con Django, necesitas instalar
flup
, una librería Python para manejar FastCGI. Algunos usuarios han
reportado páginas que explotaron con versiones antiguas de flup
, por lo
cual puedes querer utilizar la última versión SVN. Puedes conseguir flup
en
http://www.djangoproject.com/r/flup/.
20.4.2. Ejecutando tu Servidor FastCGI
FastCGI opera sobre un modelo cliente/servidor, y en la mayoría de los casos estarás iniciando el proceso servidor FastCGI por tu cuenta. Tu servidor Web (ya sea Apache, lighttpd, o algún otro) hace contacto con tu proceso Django- FastCGI solo cuando el servidor necesita cargar una página dinámica. Como el demonio ya está ejecutando su código en memoria, puede servir la respuesta muy rápido.
Nota Si estás en un sistema de hosting compartido, probablemente estés forzado
a usar procesos FastCGI manejados por el Web server. Si estás en esta
situación, debes leer la sección titulada "Ejecutando Django en un
proveedor de Hosting compartido con Apache
_", más abajo.
Un servidor Web puede conectarse a un servidor FastCGI de dos formas: usando un socket de dominio Unix, (un named pipe en sistemas Win32) o un socket TCP. Lo que elijas es una cuestión de preferencias; normalmente un socket TCP es más fácil debido a cuestiones de permisos.
Para iniciar tu servidor, primero cambia al directorio de tu proyecto (donde
está tu manage.py
), y ejecuta manage.py
con el comando runfcgi
:
$ ./manage.py runfcgi [options]
Si especificas help
como única opción después de runfcgi
, se mostrará
una lista de todas las opciones disponibles.
Necesitarás especificar un socket
o si no host
y port
.
Entonces, cuando configures tu servidor Web, solo necesitas apuntarlo al
socket o host/port que especificaste cuando iniciaste el servidor FastCGI.
Algunos ejemplos pueden ayudar a explicarlo:
Ejecutar un servidor 'threaded' en un puerto TCP:
$ ./manage.py runfcgi method=threaded host=127.0.0.1 port=3033
Ejecutar un servidor preforked sobre un socket de dominio Unix:
$ ./manage.py runfcgi method=prefork socket=/home/user/mysite.sock pidfile=django.pid
Ejecutar sin demonizar (ejecutar en segundo plano) el proceso (es bueno para el debugging):
$ ./manage.py runfcgi daemonize=false socket=/tmp/mysite.sock
20.4.2.1. Detener el Demonio FastCGI
Si tienes el proceso ejecutando en primer plano, es fácil detenerlo:
simplemente presiona Ctrl+C para detenerlo y salir del servidor FastCGI. Si
estás tratando con procesos en segundo plano, necesitarás recurrir al comando
kill
de Unix.
Si especificas la opción pidfile
en manage.py runfcgi
, puedes detener
el demonio FastCGI en ejecución de esta forma:
$ kill `cat $PIDFILE`
donde $PIDFILE
es el pidfile
que especificaste.
Para reiniciar con facilidad tu demonio FastCGI en Unix, pedes usar este breve script en la línea de comandos:
#!/bin/bash
# Replace these three settings.
PROJDIR="/home/user/myproject"
PIDFILE="$PROJDIR/mysite.pid"
SOCKET="$PROJDIR/mysite.sock"
cd $PROJDIR
if [ -f $PIDFILE ]; then
kill `cat -- $PIDFILE`
rm -f -- $PIDFILE
fi
exec /usr/bin/env - \
PYTHONPATH="../python:.." \
./manage.py runfcgi socket=$SOCKET pidfile=$PIDFILE
20.4.3. Usando Django con Apache y FastCGI
Para usar Django con Apache y FastCGI, necesitarás que Apache esté instalado y configurado, con mod_fastcgi instalado y habilitado. Consulta la documentación de Apache y mod_fastcgi para instrucciones detalladas: http://www.djangoproject.com/r/mod_fastcgi/.
Una vez que hayas completado la configuración, apunta Apache a tu instancia
FastCGI de Django editando el archivo httpd.conf
(de la configuración de
Apache). Necesitarás hacer dos cosas:
- Usar la directiva
FastCGIExternalServer
para especificar la localización de tu servidor FastCGI. - Usar
mod_rewrite
para apuntar las URLs a FastCGI según sea necesario.
20.4.3.1. Especificando la Localización del Servidor FastCGI
La directiva FastCGIExternalServer
le dice a Apache como encontrar tu
servidor FastCGI. Como se explica en los documentos de FastCGIExternalServer
(http://www.djangoproject.com/r/mod_fastcgi/FastCGIExternalServer/), puedes
especificar un socket
o un host
. Aquí hay ejemplos de ambos:
Conectar con FastCGI mediante un socket o un pipe con nombre:
FastCGIExternalServer /home/user/public_html/mysite.fcgi -socket /home/user/
mysite.sock
Conectar con FastCGI mediante TCP:
FastCGIExternalServer /home/user/public_html/mysite.fcgi -host 127.0.0.1:3033
En los dos casos, el directorio /home/user/public_html/ debe existir,
aunque el archivo /home/user/public_html/mysite.fcgi
no necesariamente
tiene que existir. Es solo una URL usada por el servidor Web internamente --
un enganche para indicar que las consultas en esa URL deben ser manejadas por
FastCGI. (Más sobre esto en la siguiente sección.)
20.4.3.2. Usando mod_rewrite para apuntar URLs hacia FastCGI
El segundo paso es decirle a Apache que use FastCGI para las URLS que coincidan
con cierto patrón. PAra hacer esto, usa el módulo mod_rewrite y reescribe las
URLs hacia mysite.fcgi
(o donde hayas especificado en la directiva
FastCGIExternalServer
, como se explicó en la sección anterior).
En este ejemplo, le decimos a Apache que use FastCGI para manejar cualquier
consulta que no represente un archivo del sistema de archivos y no empiece con
/media/
. Probablemente éste sea el caso más común, si estás usando el sitio
de administración de Django:
<VirtualHost 12.34.56.78>
ServerName example.com
DocumentRoot /home/user/public_html
Alias /media /home/user/python/django/contrib/admin/media
RewriteEngine On
RewriteRule ^/(media.*)$ /$1 [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ /mysite.fcgi/$1 [QSA,L]
</VirtualHost>
20.4.4. FastCGI y lighttpd
lighttpd (http://www.djangoproject.com/r/lighttpd/) es un servidor Web liviano usado habitualmente para servir archivos estáticos. Admite FastCGI en forma nativa y por lo tanto es también una opción ideal para servir tanto páginas estáticas como dinámicas, si tu sitio no tiene necesidades específicas de Apache.
Asegúrate que mod_fastcgi
está en tu lista de modulos, en algún lugar
después de mod_rewrite
y mod_access
, y antes de mod_accesslog
.
Probablemente desees también mod_alias
, para servir medios de
administración.
Agrega lo siguiente a tu archivo de configuración de lighttpd:
server.document-root = "/home/user/public_html" fastcgi.server = ( "/mysite.fcgi" => ( "main" => ( # Use host / port instead of socket for TCP fastcgi # "host" => "127.0.0.1", # "port" => 3033, "socket" => "/home/user/mysite.sock", "check-local" => "disable", ) ), ) alias.url = ( "/media/" => "/home/user/django/contrib/admin/media/", ) url.rewrite-once = ( "^(/media.*)$" => "$1", "^/favicon\.ico$" => "/media/favicon.ico", "^(/.*)$" => "/mysite.fcgi$1", )
20.4.4.1. Ejecutando Múltiples Sitios Django en Una Instancia lighttpd
lighttpd te permite usar "configuración condicional" para permitir la configuración personalizada para cada host. Para especificar múltiples sitios FastCGI, solo agrega un bloque condicional en torno a tu configuración FastCGI para cada sitio:
# If the hostname is 'www.example1.com'...
$HTTP["host"] == "www.example1.com" {
server.document-root = "/foo/site1"
fastcgi.server = (
...
)
...
}
# If the hostname is 'www.example2.com'...
$HTTP["host"] == "www.example2.com" {
server.document-root = "/foo/site2"
fastcgi.server = (
...
)
...
}
Puedes también ejecutar múltiples instalaciones de Django en el mismo sitio
simplemente especificando múltiples entradas en la directiva fastcgi.server
.
Agrega un host FastCGI para cada una.
20.4.5. Ejecutando Django en un Proveedor de Hosting Compartido con Apache
Muchos proveedores de hosting compartido no te permiten ejecutar tus propios
demonios servidores o editar el archivo httpd.conf
. En estos casos, aún es
posible ejecutar Django usando procesos iniciados por el sevidor Web.
Nota Si estás usando procesos iniciados por el servidor Web, como se explica en esta sección, no necesitas iniciar el servidor FastCGI por tu cuenta. Apache iniciará una cantidad de procesos, escalando según lo necesite.
En el directorio raíz de tu Web, agrega esto a un archivo llamado .htaccess
:
AddHandler fastcgi-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L]
Después, crea un pequeño script que le diga a Apache como iniciar tu programa
FastCGI. Crea un archivo mysite.fcgi
, colócalo en tu directorio Web, y
asegúrate de hacerlo ejecutable:
#!/usr/bin/python
import sys, os
# Add a custom Python path.
sys.path.insert(0, "/home/user/python")
# Switch to the directory of your project. (Optional.)
# os.chdir("/home/user/myproject")
# Set the DJANGO_SETTINGS_MODULE environment variable.
os.environ['DJANGO_SETTINGS_MODULE'] = "myproject.settings"
from django.core.servers.fastcgi import runfastcgi
runfastcgi(method="threaded", daemonize="false")
20.4.5.1. Reiniciando el Server Iniciado
Si cambias cualquier código Python en tu sitio, necesitarás decirle a FastCGI
que el código ha cambiado. Pero no hay necesidad de reiniciar Apache en este
caso the. Sólo volver a subir mysite.fcgi
— o editar el archivo — de
manera que la fecha y hora del archivo cambien. Cuando Apache ve que el archivo
ha sido actualizado, reiniciará tu aplicación Django por ti.
Si tienen acceso a la línea de comandos en un sistema Unix system, puedes hacer
esto fácilmente usando el comando touch
:
$ touch mysite.fcgi