martes, 11 de octubre de 2016

Nginx trabajando con Apache2 y Mod_WSGI

Hola a todos,

Estos días he estado leyendo documentación sobre alternativas al Apache para mejorar el rendimiento de nuestro servidor en la raspberry y he visto soluciones interesantes.

Apache funciona perfectamente sirviendo ficheros estáticos de nuestro proyecto en Django, pero consume más recursos que otros servidores web. Buscando alternativas por internet me topé con un servidor web el cual desconocía su existencia hasta ahora: nginx.

Antes de nada decir que no voy a implantar nginx (por ahora), quedaría para una futura mejora, pero si voy a mencionarlo y la posibilidad de trabajar conjuntamente con Apache para repartirse el trabajo. 

Tanto Nginx como Apache son dos servidores web potentes y eficaces. Apache es el servidor que más usado actualmente, Nginx, desde su lanzamiento público en 2006, es ahora el segundo servidor web más usado. Las razones de la popularidad de cada respectivo servidor son claras: el poder de Apache y velocidad de nginx son bien conocidos. Sin embargo, ambos servidores tienen inconvenientes: Apache es consume demasiada memoria del servidor, mientras que Nginx necesita la ayuda de php-FPM o módulos similares para servir contenido dinámico.
Sin embargo, podemos combinar los dos servidores para conseguir el máximo rendimiento, con Nginx como servidor de ficheros estáticos en el front-end y Apache se encargará del procesamiento dinámico en backend.

Este sería el escenario tradicional de un servidor web:





Solemos utilizar Apache para servir cualquier tipo de contenido a través de una petición HTTP, pero en Apache cargamos habitualmente muchos módulos necesarios para que nuestras aplicaciones funcionen correctamente, empezando por el mismísimo PHP, pero que no necesitamos para servir contenidos estáticos (imágenes, archivos css o javascript, archivos comprimidos…).

Lo que se pretende hacer es separar de una manera sencilla las peticiones esta´ticas de las dinámicas con el fin de redirigirlas a distintos servicios y conseguir qeu las peticiones estáticas consumiesen muchos menos recursos ya que las podríamos hacer con un servidor mucho más ligero que Apache: Nginx

Este sería el esquema de red al que se pretende llegar





Todas las peticiones HTTP son recibidas en el puerto 80 por un servidor mucho más ligero que Apache (nginx, lighttpd) que se encarga de servir directamente los contenidos estáticos desde el disco y de redirigir las solicitudes dinámicas al Apache de siempre que ahora escucha en el puerto 8080, es decir, el servidor ligero actúa como proxy para las peticiones de contenidos dinámicos.

 El primer paso, por tanto, es instalar y configurar Nginx para que actúe como proxy completo.

Pondremos a Nginx para que escuche en el puerto 80 y redirigirá las peticiones dinámicas a Apache en el puerto 8080.

Si se ha entendido la idea, es precisamente lo que buscaba. En caso de darme tiempo o en el futuro lo desarrollaré para que mi servidor de domótica vaya más fluído.

Un saludo.

Hacer que Apache sirva los ficheros estáticos

Si habéis seguido todas mis entradas os dareis cuenta de que Apache aún no es capaz de servir en red los ficheros estáticos y las vistas de las páginas se quedan en la base, viéndose algo cutres.

Solamente hay que hacer una pequeña modificación en un fichero de configuración para hacer que sea capaz de cargar los estilos y las imágenes.

Si recordamos cuando instalamos Apache creamos un nuevo sitio en el directorio /etc/apache2/sites-available el cual se llamaba domobois.conf. Este fichero indicaba básicamente donde estaba el script de conexión entre Apache y nuestro proyecto de Django.

El fichero en cuestión tenía esta pinta



Para que sirva ficheros estáticos únicamente, según la documentación hay que añadirle unas cuántas líneas más.

https://docs.djangoproject.com/es/1.10/ref/contrib/staticfiles/
https://docs.djangoproject.com/es/1.10/howto/deployment/wsgi/modwsgi/

Lo dejamos de la siguiente manera









Lo que se hace es definir un alias con la ruta estática donde se encuentran nuestros archivos estáticos.

También es necesario modificar el settings.py de nuestro proyecto, que si recordamos se encontraba en la ruta /var/www/domobois/domobois/settings.py 

El primer lugar donde inicia el manejo de los archivos estáticos reside en este archivo, tenemos líneas exclusivamente dedicadas al manejo del contenido estático.
Existen 4 elementos: STATIC_ROOT, STATIC_URL, STATICFILES_DIRS, STATICFILES_FINDERS. Cada uno de ellos con un propósito documentado en el mismo archivo settings.py a modo de comentario.

Debemos prestar atención a STATICFILES_DIRS, este elemento permite declarar la ruta, desde la cual se enlazará el contenido estático.

Veamos como debe quedar el fichero:

 

Tenemos en la documentación más información a lo que se refieren estas variables en este link

Por último, utilizamos el comando  ./manage.py collectstatic para crear todos los archivos estaticos referidos a nuestro proyecto desde el directorio donde se encuentra nuestro manage.py del proyecto.

Probamos si funcionan ahora los archivos estáticos, pero no sin antes hacer un sudo service apache2 restart para reiniciar nuestro servidor apache.

En este momento, si abrimos en el navegador de cualquier dispositivo conectado a nuestra red LAN y tecleamos http://192.168.0.100/domobois debería de aparecer el index de nuestro proyecto django. O al menos a mi sí ;)

Un saludo.

martes, 4 de octubre de 2016

Resumen: Apache + Django + Mod_WSGI

Hola de nuevo,
revisando post anteriores he visto que hay cosas que me he extendido bastante con instalaciones y que para un uso básico o para probar si funciona no hacen falta, del estilo de MySQL o PhpMyAdmin, nos los podemos cargar y funcionará igual.

Así que voy a hacer un breve resumen de todo lo básico y necesario que nos hace falta instalar para que funcione correctamente.

  • Si algo os ha salido mal en pasos anteriores y quereis volver a empezar desde 0 seguid estos pasos para eliminar los paquetes y configuraciones antiguas: 

sudo apt-get remove apache2-* --purge
sudo apt-get autoremove
sudo apt-get update
sudo apt-get upgrade

 Con esto ya podréis volver a empezar de nuevo sin configuraciones antiguas de apache.

  • Ahora comenzamos con los paquetes necesarios para instalar: 
  1. Instalar Python: sudo apt-get install python
  2. Instalar Apache: sudo apt-get install apache2
  3. Instalar Mod_WSGI: sudo apt-get install libapache2-mod-wsgi
  4. Instalar Django: sudo apt-get install python-django
Instalando los paquetes anteriores teneis más que suficiente para que funcione apache con Django y los proyectos definidos con Django.

Para la configuración básica entre Apache + Mod_WSGI + Django revisar esta entrada del blog.

miércoles, 21 de septiembre de 2016

Django + Apache + Configuración MOD_WSGI para usarlo en red local

Hasta ahora hemos instalado por separado las piezas del puzzle para tener en marcha en red local o desde internet nuestro servidor de domótica, pero no los hemos conectado entre ellos.

En principio, necesitamos hacer que Apache, incorpore un soporte para servir archivos Python. Para ello, necesitaremos habilitarle un módulo, que brinde este soporte.

Existen varios módulos de Apache que brindan soporte para correr archivos Python. Uno de los más populares es el módulo mod_python, que sin embargo, presenta algunos problemas que pueden prevenirse, utilizando el módulo mod_wsgi el cual utilizaremos en este proyecto.

Podemos ver la documentación más extensa asociada a esta parte del proyecto en la documentación:
https://code.google.com/archive/p/modwsgi/wikis/QuickConfigurationGuide.wiki
https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/
https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/modwsgi/

Vamos a ver como instalar y configurar mod_wsgi:

  • Para instalarlo simplemente ejecutamos: sudo apt-get install libapache2-mod-wsgi

  • Para configurarlo: 
Primeramente creamos un proyecto de django. Nuestro proyecto se llamará domobois crearemos el proyecto con el comando:

sudo django-admin.py startproject /var/www/domobois

Al final nos quedará una estructura de directorios como la de la imagen anterior:


 

En este momento el diretorio que no existe es el nombrado como apache. Lo dejamos creado con el comando  sudo mkdir /var/www/domobois/domobois/apache. Más adelante definiremos el archivo django.wsgi que por ahora no existe y servirá para conectar apache con nuestro proyecto de python.

Nuestra aplicación se llamará “domobois”.
Así que dentro del directorio /etc/apache2/sites-available/ creamos el archivo domobois.conf

Es importante la extensión *.conf ya que sin ella el servicio de apache al activar el sitio domobois no será capaz de reconocer el nuevo sitio y activarlo como veremos más adelante. Prestar especial atención a esto, porque en la mayoría de los tutorial que existen por internet no le ponen la extensión y luego al intentar activarlo no es capaz de reconocer el nuevo sitio.

Dentro del archivo de configuración /etc/apache2/sites-available/domobois.conf escribimos:



Lo que se define en él es básicamente la URL de conexión desde donde se accederá a apache y la ruta donde está ubicado el script de conexión que conecta el apache con el proyecto de django. En él están definidos los parámetros de conexión. También se definen los permisos del directorio donde se encuentra el script de conexión. En este caso se dan permisos de acceso a la carpeta del apache que se definió al principio del documento. Se podrá acceder desde cualquier dirección con la directiva "Allow from all" y si el servidor es permitido con la directiva "Order allow, deny".

Con esta configuración todo el mundo podrá acceder al directorio del apache que creamos dentro del proyecto de django. Lo que voy a comentar ahora es un paso alternativo si queremos securizar o cerrar un poco más la configuración, pero no es necesario para que funcione.
El único usuario que es necesario que lea la configuración de dentro de la carpeta /var/www/domobois/domobois/apache es el usuario que utiliza apache, que por defecto es www-data. Idem para el grupo.
Cambiamos el propietario y grupo del directorio:
sudo chown -R www-data:www-data /var/www/domobois/domobois/apache


A continuación generamos el script de conexión "django.wsgi" que nos quedó pendiente.
Para ello, creamos y editamos el fichero:

sudo nano /var/www/domobois/domobois/apache/django.wsgi



 Para entendernos... Cuando un usuario hace una petición a la URL de la ip de la raspberry /domobois, apache lee el archivo domobois.conf del directorio sites-available, sabe que hay un script de conexión en la ruta /var/www/domobois/domobois/apache/django.wsgi y se va a leerlo con el usuario www-data. Este archivo es la conexión que le hace falta al apache para recuperar la aplicación de python y devolvérsela al usuario. A continuación mostramos un esquema.


Una vez definido el nuevo sitio, tenemos que activarlo en el apache y reiniciar la configuración. Para ello tenemos el comando:

sudo a2ensite

Nos preguntará que sitio queremos activar y le diremos que domobois.

Tal como nos dice el terminal, es necesario reiniciar apache para cargar la nueva configuración:

sudo service apache2 reload

Si intentamos acceder ahora mismo al sitio en red mediante la URL http://IPRASPBERRY/domobois
nos lanzará un error del estilo "error interno en el servidor: 500".


Para solucionarlo es necesario modificar el fichero /var/www/domobois/domobois/settings.py

Dentro de él se encuentra la directiva "ALLOWED_HOSTS", la que define que tipo de accesos se pueden tener en el proyecto de django. Para que funcione desde el exterior, es necesario permitir que apache, desde el propio servidor le deje hacer peticiones al proyecto de django, por lo que modificamos la línea y la dejamos de la siguiente manera:

ALLOWED_HOSTS = ['localhost', '127.0.0.1']

Volvemos a recargar la la página de la dirección  http://IPRASPBERRY/domobois y si todo funciona adecuadamente debería devolver el proyecto de django.
En mi caso como aún no tengo desarrollado el proyecto de django nos devuelve un error de path URL dado que como ya digo, no está desarrollado, PERO, sabemos que funciona.



Si no funciona, probad a recargar otra vez la configuración con: sudo service apache2 restart



Un consejo: Backup ahora que el servidor web funciona sin problemas

Archivos importantes a guardar... 
  1. /etc/apache2/sites-available/domobois.conf 
  2. /var/www/domobois/domobois/apache/domobois.wsgi
  3. /var/www/domobois/domobois/settings.py
O más a lo bruto, los directorios...
  1. /etc/apache2/
  2. /var/www/domobois

Comando para hacer backups (tar)
tar -cvf archivo.tar /dir/a/comprimir/
-c : indica a tar que cree un archivo.
-v : indica a tar que muestre lo que va empaquetando.
-f : indica a tar que el siguiente argumento es el nombre del fichero.tar.