martes, 6 de marzo de 2007

Django con Fast-Cgi II

Después de varios intentos, logré configurar Django para ser servido a trevés de un vhost de Apache y FastCGI.

Primero, el proyecto de Django existe en algún lugar de mi PC, fuera del camino de Apache y sin preocuparse por su existencia. Se utiliza:

python manage.py runfcgi daemonize=true method=threaded host=$FCGIHOST port=$FCGIPORT pidfile=$FCGIPIDFILE

para ejecutar el servidor FastCGI.

Para versiones anteriores de Apache, basta con bajar mod_fastcgi del sitio de FastCgi, pero para Apache 2.2, hay que parchar el código. Craic ofrece una muy buena guía para arreglar el mod_fastcgi.c:271: error: 'ap_null_cleanup' undeclared (first use in this function) que aparece al intentar compilar.

Después de haber instalado mod_fastcgi, dentro de http.conf coloqué las siguientes indicaciones:

# Al final de los módulos a incluir:

LoadModule fastcgi_module modules/mod_fastcgi.so

# Fastcgi va después de estas líneas

User apache
Group apache
<IfModule mod_fastcgi.c>
FastCgiIpcDir /tmp/fcgi_ipc/
AddHandler fastcgi-script .fcgi

# Servidor externo para usar django con fastcgi.
FastCGIExternalServer /var/www/fastcgi/fastcgi.fcgi -host 127.0.0.1:3033

# En Apache 2.2 es necesario especificar permisos de acceso.
<Directory "/usr/local/apache2/fastcgi">
Order allow,deny
Allow from all
</Directory>
</IfModule>

Como (por motivos particulares de mi proyecto) quiero acceder a FastCGI desde diferentes vhosts hice que FastCGIExternalServer apunta a alguna dirección neutra, en este caso /var/www/fastcgi/fastcgi.fcgi.

Dentro de la configuración de vhost indico:


DocumentRoot "/sudomain_path/dynamic_docs"
Options +FollowSymLinks

RewriteEngine On
#Todas aquellas direcciones, menos '/', que no correspondan a un archivo en disco, serán atendidas por el servidor FastCGI.

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -!f #Si el archivo estático existe en DocumentRoot, se sirve ese.
RewriteCond %{REQUEST_URI} !(/var/www/fastcgi/fastcgi.fcgi) #El 'pseudo archivo' de FastCGI.
RewriteCond %{REQUEST_URI} !(/media) #No quiero que FastCGI sirva imágenes, css, etc.
RewriteCond %{REQUEST_URI} !(/static) #Un lugar para httpdocs :)
RewriteRule ^/(.+)$ /var/www/fastcgi/fastcgi.fcgi/$1 [QSA,L] #Ojo: '/' no es para FastCGI, así preservo index como valor por defecto estático. Si quiero que django sirva '/' también, uso RewriteRule ^(.+)$ /var/www/fastcgi.fcgi$1 [QSA,L]

Alias "/static" "/subdomain_path/httpdocs"
<Directory subdomain_path/httpdocs>
# Aquí insisto en usar scripts de python dentro de httpdocs. Sólo si el archivo acaba en .py :)
<IfModule mod_python.c>
<Files ~ (\.py$)>
SetHandler python-program
PythonHandler mod_python.publisher
</Files>
</IfModule>
</Directory>

Demasiados semáforos

Hoy Apache murió súbitamente cuando intenté configurar algunas cosas que ya había modificado antes. Obtuve:

[emerg] (28)No space left on device: Couldn't create accept lock

Seguido de algunos errores más. Afortunadamente la solución estaba a la mano: Apache había sobrepoblado al sistema de semáforos. Aún me pregunto porqué hizo tantos. La parte importante es utilizar:

[]$ for semid in `ipcs -s | grep apache | cut -f2 -d" "`; do ipcrm -s $semid; done

Cuando apache ya no esté siendo ejecutado, para eliminar a los semáforos fantasmas.