Sólo un idiota puede ser totalmente feliz.
Mario Vargas Llosa
En los foros
Comentarios recientes
- Hola a todos, y me uno a la
17 semanas 5 días atrás - en ubunut 9.10 no me da la
18 semanas 1 día atrás - Quisiera saber si con un plan
18 semanas 2 días atrás - Gracias!!!! me estaba
19 semanas 11 horas atrás - estoy pensando cambiarme a
19 semanas 1 día atrás - Hola,
mi experiencia con los
19 semanas 1 día atrás - Buenos días
He visto algunos
19 semanas 2 días atrás - Alexis vuelve!, que estoy del
19 semanas 3 días atrás - HOLA soy nuevo en esto soy de
19 semanas 5 días atrás - Hola amigos, recien encuentro
20 semanas 18 horas atrás
Enciende tus proyectos Django con Nginx, Apache y mod_wsgi
Llega un momento en que todo desarrollador Django debe pensar en cómo implementará sus proyectos en un servidor de producción. La primera vez que lo hice creí que la mejor opción era utilizar Lighty, Apache, mod_proxy y mod_python; poco después descubrí que estaba equivocado. Usar Apache como servidor web al frente para gestionar todas las peticiones a un proyecto Django y pasar, vía mod_proxy, pedidos de contenido estático a Lighty es una mala idea, con esta configuración Apache trabaja incluso para archivos que no tiene que servir, usando más memoria y CPU que Lighty.
Luego de leer algunos comentarios en el artículo original y más sobre la implementación de Django pude confirmar que lo mejor era tener al servidor web de contenido estático al frente y Apache detrás, procesando las páginas generadas por Django.
Reemplacé Lighty con Nginx, que de acuerdo a muchos parece ser más estable, y opté por mod_wsgi en vez de mod_python para conectar Apache con Django. mod_wsgi usa además menos memoria y está preparado para sitios con mayores exigencias. No hay necesidad de mod_proxy en Apache pues Nginx se encarga ahora del trabajo de proxy.
La siguiente es una breve guía, muy precisa y fácil de seguir, para desarrolladores web que saben cómo administrar sus servidores. No tocaré temas como seguridad, memcached, configuración de Django, bases de datos, Apache, DNS u otros aspectos básicos de GNU/Linux. Por supuesto que todos estos temas son también importantes y debes saber cómo encargarte de ellos.
El plan
Esta guía te permitirá configurar un servidor para Django en Ubuntu e incluye todos los pasos para:
- Configurar un dominio para tu proyecto en Django.
- Crear una estructura de directorios para tus sitios en Django.
- Configurar Apache con mod_wsgi para Django.
- Configurar Nginx.
- Servir archivos estáticos para la sección de administración de Django.
- Mostrarle tu próximo éxito en Django al mundo.
Luego de seguir estos pasos tendrás un sitio corriendo con Nginx al frente y Apache hablando con Django detrás. Nginx se encargará del contenido estático y pasará las peticiones de Django para Apache y mod_wsgi.
He probado los pasos a continuación en tres servidores Ubuntu (dos corriendo 8.10, Intrepid Ibex, y otro con 7.10, Gutsy Gibbon) pero todo debería funcionar muy parecido en otras distribuciones de GNU/Linux.
¿Empezamos?
Configurar un dominio para tu proyecto en Django
Muchos tenemos más de un sitio web en un solo servidor, yo tengo muchos con Drupal y algunos con Django, así que consideraré el caso de dos dominios: cataybea.com hospeda nuestro proyecto en Django y example.com cualquier otro sitio. Casi todos los pasos en la guía se refieren a cataybea.com y solo menciono a example.com para tener idea del contexto. Obviamente deberás reemplazar todos los nombres de dominio de ejemplo con los tuyos.
Usaremos un par de direcciones IP privadas por ahora, luego puedes reemplazarlas por direcciones públicas y configurar un servidor DNS en producción. Por ahora basta con añadir un par de líneas en /etc/hosts, es lo que siempre hago en mis servidores de desarrollo.
192.168.0.180 cataybea.com
192.168.0.192 example.com
Estoy usando 192.168.0.180 y dos puertos, 80 y 8080, para servir el sitio en Django desde cataybea.com. El puerto predeterminado 80 será usado por Nginx para contenido estático y Django buscará archivos en el directorio /media. El puerto 8080 será usado por Apache para procesar las peticiones a Django.
Crear una estructura de directorios para tus sitios en Django
La estructura de directorios para un proyecto Django depende de las preferencias de cada desarrollador, yo uso /home/alexis/djcode y el nuevo proyecto se llamará cataybea; por lo tanto, debemos ejecutar:
mkdir /home/alexis/djcode
cd /home/alexis/djcode/
django-admin.py startproject cataybea
Ahora creamos algunos directorios adicionales:
mkdir /home/alexis/djcode/cataybea/apache
mkdir /home/alexis/djcode/cataybea/logs
mkdir /home/alexis/djcode/cataybea/media
¿Para qué sirve cada uno? apache contendrá un script Python para configurar mod_wsgi, logs es para los registros de error y acceso de Apache y Nginx, y media será usado por Nginx para los archivos de contenido estático que usará Django.
Luego puedes manejar todo el árbol en /home/alexis/djcode/cataybea con tu herramienta de control de versiones favorita.
Anota todas las rutas correctamente pues las necesitarás en los archivos de configuración a continuación.
Configurar Apache con mod_wsgi para Django
Asumo que ya tienes un servidor Apache funcionando correctamente y solo debemos cambiar algunos detalles para trabajar con Django. Vamos a tener dos servidores web corriendo al mismo tiempo y debemos estar seguros que no habrá conflictos entre las direcciones IP y los puertos que usaremos. Empezamos modificando /etc/apache2/ports.conf:
Listen 192.168.0.192:80
Listen 192.168.0.180:8080
#Listen 80
Nota que he comentado la opción predeterminada, Listen 80, que indicaba que Apache use todas las direcciones IP disponibles, y he preferido especificar solo los valores que usaré. Si necesitas trabajar con SSL deberás incluir las referencias al puerto 443 de la misma manera.
Si estás usando virtual hosts en Apache confirma que esté escuchando en las direcciones y puertos correctos. Yo tengo esto en /etc/apache2/sites-enabled/example.com:
NameVirtualHost 192.168.0.192
Reinicia Apache y confirma que todos tus sitios funcionan correctamente. Yo siempre pruebo luego de cada paso y te sugiero hacer lo mismo.
sudo /etc/init.d/apache2 restart
Este es el momento de añadir mod_wsgi en Apache. Versiones recientes de Ubuntu tienen el módulo en el repositorio:
sudo apt-get install libapache2-mod-wsgi
En versiones antiguas, como Gutsy, debes encontrar el archivo .deb y usar dpkg -i para instalarlo.
Aora creamos un archivo de configuración para cataybea.com en /etc/apache2/sites-available/cataybea.com:
<VirtualHost 192.168.0.180:8080>
ServerAdmin alexis@ventanazul.com
ServerName www.cataybea.com
ServerAlias cataybea.com
<Directory /home/alexis/djcode/cataybea/apache/>
Order deny,allow
Allow from all
</Directory>
LogLevel warn
ErrorLog /home/alexis/djcode/cataybea/logs/apache_error.log
CustomLog /home/alexis/djcode/cataybea/logs/apache_access.log combined
WSGIDaemonProcess cataybea.com user=www-data group=www-data threads=25
WSGIProcessGroup cataybea.com
WSGIScriptAlias / /home/alexis/djcode/cataybea/apache/cataybea.wsgi
</VirtualHost>
Nota la dirección IP y puerto: 192.168.0.180:8080. En ningún momento este sitio se accederá directamente sino a través del proxy desde Nginx. Veremos cómo en la siguiente sección.
Para terminar con Apache creamos un script en Python que configurará nuestro sitio para comunicarse con Django vía mod_wsgi, el script debe estar en /home/alexis/djcode/cataybea/apache/cataybea.wsgi e incluir las siguientes líneas:
import os, sys
apache_configuration= os.path.dirname(__file__)
project = os.path.dirname(apache_configuration)
workspace = os.path.dirname(project)
sys.path.append(workspace)
sys.path.append('/usr/lib/python2.5/site-packages/django/')
sys.path.append('/home/alexis/djcode/cataybea')
os.environ['DJANGO_SETTINGS_MODULE'] = 'cataybea.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
No reinicies Apache aún, necesitamos completar otros pasos antes.
Configurar Nginx
Nginx hace dos cosas: servir contenido estático desde http://cataybea.com/media y pasar peticiones para Django vía Apache. Primero lo instalamos:
sudo apt-get install nginx
Y luego removemos el sitio predeterminado de Nginx:
sudo rm /etc/nginx/sites-enabled/default
Apache y Nginx deben utilizar el mismo usuario, para Ubuntu es www-data, y el archivo /etc/nginx/nginx.conf debe lucir como este:
user www-data;
worker_processes 2;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
tcp_nodelay on;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
En mi caso worker_processes contiene el número de núcleos en mi servidor: 2.
Para configurar el sitio cataybea.com en Nginx crea /etc/nginx/sites-available/cataybea.com:
server {
listen 192.168.0.180:80;
server_name www.cataybea.com cataybea.com;
access_log /home/alexis/djcode/cataybea/logs/nginx_access.log;
error_log /home/alexis/djcode/cataybea/logs/nginx_error.log;
location / {
proxy_pass http://192.168.0.180:8080;
include /etc/nginx/proxy.conf;
}
location /media/ {
root /home/alexis/djcode/cataybea/;
}
}
y luego ejecuta:
sudo ln -s /etc/nginx/sites-available/cataybea.com /etc/nginx/sites-enabled/cataybea.com
Para procesar las peticiones a Django vía Apache debemos crear /etc/nginx/proxy.conf e incluir estas líneas:
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
Nota que $host, $remote_addr y $proxy_add_x_forwarded_for son variables manejadas por Nginx, no debes cambiar nada más en proxy.conf para una configuración básica. Cuando empecé con Nginx pensé que debía reemplazar estas variables con mis valores pero no es así.
Ahora reinicia Nginx:
sudo /etc/init.d/nginx restart
y Apache:
sudo /etc/init.d/apache2 restart
Eso debe bastar. Si visitas http://cataybea.com verás contenido de Django (puede ser la página de bienvenida, alguna de tus vistas o una página 404 dependiendo del estado de tu proyecto). Para probar Nginx crea un archivo test.htm con algo de HTML en /home/alexis/djcode/cataybea/media y visita http://cataybea.com/media/test.htm.
Servir archivos estáticos para la sección de administración de Django (opcional)
Si piensas utilizar la aplicación de administración edita /home/alexis/djcode/cataybea/settings.py, configura tu base de datos, añade 'django.contrib.admin' al tuple INSTALLED_APPS y cambia la línea de ADMIN_MEDIA_PREFIX por:
ADMIN_MEDIA_PREFIX = '/media/admin/'
Ahora activamos el url de administración en /home/alexis/djcode/cataybea/urls.py removiendo los comentarios en estas líneas:
from django.contrib import admin
admin.autodiscover()
y agregando en urlpatterns:
(r'^admin/', include(admin.site.urls)),
Para acceder a los archivos creamos un enlace simbólico:
cd /home/alexis/djcode/cataybea/media
ln -s /usr/lib/python2.5/site-packages/django/contrib/admin/media/ admin
y finalmente creamos el usuario administrador y ejecutamos los cambios en la base de datos:
cd /home/alexis/djcode/cataybea/media
python manage.py syncdb
Al igual que con toda modificación en código para Django debes recargar Apache para que los cambios se activen:
sudo /etc/init.d/apache2 reload
Visita http://cataybea.com/admin/, incluyendo el último slash, y estás listo.
Muéstrale tus proyecto Django al mundo
Esta configuración de Nginx y Apache es muy fácil de implementar y parece ser una de las preferidas por muchos desarrolladores Django. Es la que estoy usando para uno de mis nuevos proyectos en familia, es obvio que se trata de cataybea.com, un sitio donde con mi esposa compartiremos historias y consejos sobre cómo criamos a nuestras hijas, será divertido.
Ahora que tienes todo listo para hospedar tu próximo proyecto Django sugiero que sigas usando el servidor de desarrollo incluido hasta tener todo listo y puedas moverte a Nginx y Apache. El servidor de desarollo de Django se actualiza automáticamente luego de cada cambio en el código.
Muchas gracias a Meppum por su guía de configuración de Django y Ubuntu en la cual este artículo se inpiró.
Si tienes sugerencias para mejorar esta guía o quieres contar tu experiencia no dudes en comentar. Nos vemos y pásala bien con Django.


Participa en la discusión
En este tipo de guias, pienso
En este tipo de guias, pienso que no estaría de más añadir ejemplos enteros de los archivos de configuración... puesto que para los que tenemos errores en mitad del proceso, podamos tener una guia de algo que sabemos que está bien.
Por lo demás, muy buena guia, gracias :)-
He seguido el tutorial al pie
He seguido el tutorial al pie de la letra y no consigo ver mi site. ¿Me puedes hechar una mano?
Cuando pongo mi URL me tira el Apache el mensaje de que funciona:
ITS WORKS
Y si pongo mi URL/media/ el nginx tira lo siguiente
403 Forbidden nginx/0.5.33
Soy neofito en el tema. Capaz que es una tonteria, pero no encuentro el fallo.
Gracias por tu atención