Que tal un saludo a todos, este es mi primer articulo en <» DesdeLinux (de varios que tengo en mis borradores xD), espero les sea de utilidad 😀
Bueno, en mi nuevo y actual trabajo, en estos momentos se esta realizando la migración de varios sistemas hacia Django (que raro eh?? xD) y una de mis tareas, aparte del desarrollo, es la puesta en producción de estos, entonces como buen aprendiz, puesto que era mi primera vez poner en producción una aplicación en un servidor real :$ me puse a leer la doc oficial de cada uno de los paquetes requeridos del stack (Gunicorn y Supervisord mas que todo), y viendo que los tutoriales en español que hay no me fueron muy claros en algunos aspectos, decidí crear una mini guía con los pasos que segui para poner en producción la aplicacion, basándonos en el stack Django, Gunicorn, Supervisord, Nginx y Postgresql.
En el caso donde trabajo, los servidores aun corren con Debian Squeeze, pero la guía debería ser totalmente valida para otras distribuciones… entonces vayamos directo al grano y comencemos:
Yo trabajare como super usuario. Primero que nada, se requieren los siguientes paquetes:
PIP -> Herramienta para instalar y administrar paquetes para Python
aptitude install python-pip
Nginx -> Servidor web (lo utilizaremos como proxy invertso y para cachear los archivos estaticos ‘img, js, css’ ) Lo instalamos con:
aptitude install nginx
Supervisord – > Aplicación para administrar y supervisar nuestra aplicación, aunque sirve para mucho mas. Lo instalamos con:
aptitude install supervisor
Virtualenv -> Nos sirve para crear un entorno virtual de ejecución personalizado para nuestra aplicación. Lo instalamos con:
aptitude install python-virtualenv
Gunicorn -> Servidor web para python (esto no lo instalaremos todavía)
Asumo que ya deberían tener instalado y configurado postgresql
psycopg2 -> Conector de postgresql para python (tampoco lo instalaremos todavia)
Crear entorno virtual con virtualenv:
Primero vamos a movernos hasta el directorio de trabajo que utilizaremos para la puesta en producción:
cd /var/www/
Luego en dicho directorio crearemos el entorno virtual:
virtualenv ENV-nombreApp
Nos movemos hasta el directorio que acabo de crear virtualenv
cd ENV-nombreAPP
Copiamos la aplicación en este directorio y ahora procedemos a activar el entorno con:
source bin/activate
El prompt deberá quedar ahora como (ENV)usuario@host:
Esto hará que ahora todo lo que hagamos este almacenado en el directorio /var/www/ENV-nombreAPP/ sin afectar los paquetes del sistema
Ahora nos movemos al directorio de la aplicación:
cd nombreApp
Procedemos a instalar la lista de dependencias de la aplicación (de ser necesario), en el cual las mismas están especificadas en el archivo requirements.txt:
pip install -r requirements.txt
También podemos instalar paquetes de manera individual, por ejemplo, para instalar el conector de postgresql:
pip install psycopg2
Instalación y configuración de GUnicorn:
Para instalarlo lo hacemos de la misma manera:
pip install gunicorn
Ahora vamos a configurarlo, para ello vamos a crear un archivo llamado gunicorn-deploy.py en la raíz de nuestra aplicación, (aunque el nombre puede ser cualquiera) con el siguiente contenido:
bind = "127.0.0.1:8001" # dirección a donde accederá Nginx
logfile = "/var/www/logs/nombreApp/gunicorn.log" # dirección donde estarán los logs de la aplicación
workers = 1 # dependerá en medida de la carga de trabajo que tenga la aplicación, también depende del hardware con que se cuente
loglevel = 'info' # tipo de logging
Configuracion de Supervisord:
Ahora configuremos el supervisord, para eso generamos el fichero de configuración con
echo_supervisord_conf > /etc/supervisord.conf
Ahora editamos el archivpo de configuración:
vim /etc/supervisord.conf
Y descomentamos las siguientes lineas quitandole el ; (punto y coma):
[unix_http_server] file=/tmp/supervisor.sock [supervisord] logfile=/var/log/supervisord.log logfile_maxbytes=50MB logfile_backups=10 loglevel=debug pidfile=/var/run/supervisord.pid nodaemon=false minfds=1024 minprocs=200 [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix: [program:nombreApp] command=/var/www/ENV-nombreApp/bin/django_unicorn -c /var/www/ENV-nombreApp/nombreApp/gunicorn-deploy.py directory=/var/www/ENV-nombreApp/nombreApp/ autostart=true autorestart=true user=nombreUser redirect_stderr=true stdout_logfile=/var/www/logs/nombreApp/supervisord.log
Ahora crearemos el script para que supervisord inicie con el sistema, para eso crearemos el archivo:
vim /etc/init.d/supervisord
Y le agregamos el siguiente contenido:
# Supervisord auto-start # # description: Auto-starts supervisord # processname: supervisord # pidfile: /var/run/supervisord.pid SUPERVISORD=/usr/local/bin/supervisord SUPERVISORCTL=/usr/local/bin/supervisorctl case $1 in start) echo -n "Iniciando supervisord:" $SUPERVISORD echo ;; stop) echo -n "Deteniendo supervisord:" $SUPERVISORCTL shutdown echo ;; restart) echo -n "Deteniendo supervisord:" $SUPERVISORCTL shutdown echo echo -n "Iniciando supervisord: " $SUPERVISORD echo ;; esac
Y ahora le damos permisos de ejecución al archivo para que pueda iniciar con el sistema:
sudo chmod +x /etc/init.d/supervisord
Actualizamos los enlaces para arrancar el servicio:
sudo update-rc.d supervisord defaults
Iniciamos el servicio:
sudo /etc/init.d/supervisord start
Configurando nginx:
Este paso también es bastante sencillo, crearemos el siguiente archivo de configuración de nginx para nuestra aplicación:
vim /etc/nginx/sites-enabled/nombreApp
Y le agregaremos el siguiente contenido
server { listen 9001; # puerto donde quieren que escuche nginx server_name www.dominio.com; # o 192.168.0.100, dirección a la cual accederemos access_log /var/log/nginx/nombreApp.access.log; # donde tendremos el log de la aplicación location / { # a donde llamara nginx al acceder a www.dominio.com/ proxy_pass http://127.0.0.1:8001; proxy_set_header Host $http_host; } location /static/ { # a donde accedera nginx cuando ingresemos en www.dominio.com/static/ alias /var/www/ENV-nombreApp/nombreApp/staticfiles/; } }
Y reiniciamos nginx:
service nginx restart
Configurando Django:
Vamos a modificar el archivo de configuración de django:
vim nombreApp/settings.py
Buscamos la linea que dice DEBUG = True y le cambiamos el valor, quedando DEBUG = False
Agregamos los parámetros de la DB:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', # o mysql, o lo que estén usando 'NAME': 'nombreDB', 'USER': 'usuarioDB', 'PASSWORD': 'contrasenaDB', 'HOST': 'localhost', # o el que necesiten 'PORT': '', # o el que esten usando } }
Buscamos la linea ALLOWED_HOSTS=[] y le agregamos el dominio o la dirección por medio del cual accederemos, quedando algo como ALLOWED_HOSTS=[‘www.dominio.com’]
Configuramos el directorio para los archivos estáticos, buscamos la linea que dice STATIC_ROOT = ' '
y le cambiamos el valor, colocándole la ruta absoluta donde queremos que estén nuestros archivos estáticos, en mi caso lo deje mas o menos así STATIC_ROOT='/var/www/ENV-nombreApp/nombreApp/statics/'
Ya casi por finalizar, ejecutamos el siguiente comando:
./manage.py collectstatic
Esto nos creara una carpeta con el nombre ‘statics en la ruta que especificamos en el settings.py ‘, es allí donde estarán todos nuestros archivos estáticos.
Y por ultimo reiniciamos el supervisord para que tome los nuevos cambios:
supervisorctl restart nombreApp
Y eso seria todo, al final no era para tanto verdad? a mi me pareció sencillo 😀
Espero les sea de utilidad, saludos 😉
Tengo entendido que no se debería poner la app Django en la raiz de la carpeta del servidor web(/var/www)? por seguridad, no se si me equivoco.
Saludos.
Toda la razón!!! era algo que desconocía totalmente, actualizare la entrada 😛 y apenas regrese el lunes haré cambios en la aplicación xD
Gracias
Epale hermano buen tutorial. Hace poco también estuve en lo mismo pero en Debian 7, tuve que buscar y leer mas o menos. Te recomiendo que el entorno virtual del virtualenv lo crees en el home del usuario en una carpeta oculta.
Saludos!
jajaja ctm yo ayer documentandome de Django y vos ya vais por la galaxia 999999 Saludos men xD
Muy buen articulo =) apenas hace una semana hice el deploy de mi app de django pero lo hice con uwsgi y nginx, sabes que ventaja tiene gunicorn? he visto que lo mencionan mucho.
Da gusto ver que se esta popularizando mucho django, la verdad es el mejor framework que he visto =)
Para el STATIC_ROOT lo que hago es definir una variable global. Algo como esto:
import os
PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = os.path.join(PROJECT_PATH, '../backend/static')
Donde backend es una app que yo creé. Asi me aseguro que donde despliegue el proyecto, la ruta global sea la misma.
Interesante, lo intentaré en lo sucesivo.
A propósito, alguien sabe ¿Cómo habilitar los acentos y caracteres no ascii en una aplicación django?
He buscado por todos lados, ninguna de los siguientes métodos me funcionan:
sys.setdefaultencoding(‘utf-8’) # en sites.py
# -*- coding: utf-8 -*- # en cada archivo python
Se supone que al editar site.py, y colocar utf-8 en vez de ascii debería funcionar, pero $ file models.py me informa que mi archivo sigue siendo un ascii.
¿Alguna Sugerencia?
Ya funcionó!!!!
muy buen tutortial pero podrias hacer uno de como subir mi app en un servidor web ya en produccion
gracias