3

Cómo subir tu proyecto de Django a AWS

835Puntos

hace 8 años

Este post complementa una clase bonus de Comunidad Platzi (Gratuita) en la que aprenderás, paso a paso, cómo se instala un proyecto web escrito en Python y Django en una máquina Linux de AWS.

El proyecto

El proyecto consta de un sitio web que usa el admin de Django para administrar contenido de los cursos de Platzi mostrados en la página principal. El proyecto hace uso de archivos estáticos y media files por lo que también se hablará del manejo de los mismos. Todo el código fuente está disponible en un repositorio de Github. Dentro del proyecto notarás algunas cosas:

  • No existe un archivo único de settings.py, si no más bien, un folder settings con diferentes archivos que modularizan las configuraciones entre las que existen en el entorno de desarollo y las que existen en producción. Para usar un módulo en específico en necesario que se declare la variable DJANGO_SETTINGS_MODULE en las variables del sistema.
  • Similar al settings.py, no existe un archivo único de requirements.txt y en su lugar hay un folder separando las dependencias dependiendo del entorno en el que se trabaje.
  • Ninguna llave privada está expuesta, es decir, llaves como el SECRET_KET o la configuración de la base de datos no es empujada a los repositorios de código y en su lugar se usan expresiones como os.getenv('KEY') para obtener los valores de las variables del sistema.

El servidor

Para la demostración de la clase se usa una máquina t2.nanoque Amazon Web Services provee con Ubuntu Server. Toda la configuración del proyecto vive en el mismo servidor. Es decir, tanto la base de datos como los archivos estáticos y el código fuente son manejados por una sola máquina. Es importante mencionar que en casos donde nuestro proyecto es más grande y requiere de una mejor arquitectura, es recomendable separar cada uno de estos de manera que la base de datos tenga su propio servidor, que exista un balanceo de carga hacia las instancias que manejan el código y que la media y los estáticos sean servidos desde una CDN. El caso de instalación que veremos en este post es un método que se puede usar en cualquier servidor Linux con Ubuntu Server; por lo que no es una configuración que únicamente se pueda llevar a cabo usando AWS. Cualquier proveedor que te dé acceso a una máquina Linux es útil.

Crear el servidor

Una vez dentro de la consola de administración de Amazon Web Services sigue estos pasos:

  1. Accede a la sección de Amazon EC2
  2. Da clic en el botón Launch Instance
  3. Selecciona Ubuntu como el Sistema Operativo deseado
  4. Elige el tipo de instancia que más se adecúe a tus  necesidades
  5. En el paso 3, deja todas las configuraciones tal y como están
  6. Selecciona la cantidad de GB de almacenamiento que quieras tener en tu instancia
  7. Asigna un nombre descriptivo a la instancia
  8. Crea un nuevo grupo de seguridad con el puerto 22, 80 y 8000 abiertos desde cualquier IP por el protocolo TCP
  9. Selecciona Launch
  10. Crea nuevas llaves SSH y descargarlas al ordenador

Conectarse al servidor

Para conectarnos al servidor usaremos la llave que acabamos de descargar. Es muy importante nunca perder esta llave ya que si la perdemos no tendremos otra forma de acceder al servidor.

  1. Poner la llave en modo lectura: [shell]chmod 0400 Platzi.pem[/shell]
  2. Conectarse al servidor usando la IP pública que AWS nos asigna: [shell]sudo ssh -i Platzi.pem ubuntu@IP[/shell]

Configuración inicial del servidor

  1. Es una buena práctica que la primera acción que realicemos al conectarnos a nuestro servidor sea actualizarlo. Lo que podemos hacer con los siguientes comandos: [shell]sudo apt-get update[/shell] [shell]sudo apt-get upgrade[/shell]
  2. Luego crearemos un nuevo usuario que tenga la capacidad de correr algunos comandos de súper usuario pero que no sea súper usuario: [shell]sudo useradd -g sudo -m[/shell]
  3. Le asignamos una contraseña segura al nuevo usuario: [shell]sudo passwd [/shell]
  4. Iniciamos sesión con el nuevo usuario: [shell]su [/shell]

Instalar las dependencias necesarias

  1. Dependencias de python: [shell]sudo apt-get install python3-pip python3-dev[/shell]
  2. Dependencias de PostgreSQL: [shell]sudo apt-get install postgresql postgresql-contrib libpq-dev[/shell]
  3. Git: [shell]sudo apt-get install git[/shell]
  4. Nginx: [shell]sudo apt-get install nginx[/shell]

Configurar PostgreSQL

  1. Iniciamos sesión con el usuario postgres: [shell]sudo su postgres[/shell]
  2. Entramos al shell interactivo de postgres: [shell]psql[/shell]
  3. Creamos una base de datos: [shell]CREATE DATABASE platzi;[/shell]
  4. Creamos un usuario para la base de datos: [shell]CREATE USER freddier WITH PASSWORD ‘cvander<3’;[/shell]
  5. Le damos permisos al usuario sobre la base de datos: [shell]GRANT ALL PRIVILEGES ON DATABASE platzi TO freddier;[/shell]
  6. Salimos del shell: [shell]\q[/shell]
  7. Salimos de la sesión de postgres: [shell]exit[/shell]

Configurar el proyecto

  1. Clonar el proyecto de Github: [shell]git clone https://github.com/pablotrinidad/cursos_platzi.git platzi[/shell]
  2. Instalar virtualenv: [shell]sudo pip3 install virtualenv[/shell]
  3. Crear entorno virtual: [shell]virtualenv -p $(which python3) .venv[/shell]
  4. Activar entorno virtual: [shell]source .venv/bin/activate[/shell]
  5. Instalar dependencias para Pillow: [shell]sudo apt-get install libjpeg-dev[/shell]
  6. Ir al folder del proyecto: [shell]cd platzi[/shell]
  7. Instalar dependencias de python del proyecto: [shell]pip install -r requirements/prod.txt[/shell]
  8. Agregamos algunas variables de entorno a **~/.bashrc **para probar localmente que todo esté funcionando: [shell]vi ~/.bashrc[/shell] Las variables lucen algo similar a lo siguiente: [shell] export PLATZI_SECRET_KEY="random_key:aasdafasf"export PLATZI_DB_NAME=“platzi”; export PLATZI_DB_USER=“freddier”; export PLATZI_DB_PASSWORD=“cvander<3” export PLATZI_DB_PORT=“5432” export PLATZI_DB_HOST="localhost"export DJANGO_SETTINGS_MODULE=“platzi.settings.prod”[/shell]
  9. Leemos las variables: [shell]source ~/.bashrc[/shell]
  10. Editamos la variable **ALLOWED_HOSTS **del archivo de settings de producción: [shell]vim platzi/settings/prod.py[/shell] La variable tendrá algo como lo siguiente, donde gatos.io sea tu dominio o IP: [python]ALLOWED_HOSTS = [’.gatos.io’][/python]

Sanity Check

Hasta este punto el proyecto debe ser capaz de escribir a la base de datos y servirse usando el servidor de desarrollo y gunicorn. Probémoslo.

  1. Reflejar el modelo de Django en PostgreSQL: [shell]./manage.py migrate[/shell]
  2. Crear un super usuario: [shell]./manage.py createsuperuser[/shell]
  3. Correr servidor de desarrollo: [shell]./manage.py runserver 0.0.0.0:8000[/shell]
  4. Correr gunicorn: [shell]gunicorn platzi.wsgi -b 0.0.0.0:8000[/shell]

Si todo funcionó correctamente, los pasos 3 y 4 debieron mostrar tu sitio en la URL o IP en el puerto 8000.

Configurar Nginx

  1. Iniciar sesión como super usuario: [shell]sudo su -[/shell]
  2. Ir al directorio de Nginx: [shell]cd /etc/nginx/[/shell]
  3. Borrar los antiguos archivos de configuración: [shell]rm sites-*/default[/shell]
  4. Crear un nuevo archivo: [shell]vim sites-available/app[/shell] Con el siguiente contenido: [shell] upstream django_app { server 127.0.0.1:8000; }server {listen 80; server_name ;access_log /var/log/nginx/app.log; error_log /var/log/nginx/app.error.log;location /static { autoindex on; alias /home/platzi/platzi/staticfiles/; } location /media { autoindex on; alias /home/platzi/platzi/media/; } location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://django_app; } } [/shell]
  5. Linkear los archivos: [shell]ln -s /etc/nginx/sites-available/app /etc/nginx/sites-enabled/[/shell]
  6. Reiniciar Nginx: [shell]service nginx restart[/shell]

Configurar Gunicorn

  1. Regresamos a la sesión de Platzi: [shell]exit[/shell]
  2. Creamos foldes para los scripts y los logs: [shell]mkdir deploy logs[/shell]
  3. Creamos un script dentro de deploy: [shell]vim deploy/gunicorn_start[/shell] Con un contenido similar al siguiente: [shell] #!/bin/bashNAME=“platzi” VIRTUALENV="/home/platzi/.venv/" DJANGODIR="/home/platzi/platzi/" USER=platzi GROUP=sudo NUM_WORKERS=3 DJANGO_WSGI_MODULE=platzi.wsgiecho "Starting $NAME as whoami"cd $VIRTUALENV source bin/activate cd $DJANGODIRexport PLATZI_SECRET_KEY=“random_key:aasdafasf” export PLATZI_DB_NAME=“platzi” export PLATZI_DB_USER=“freddier” export PLATZI_DB_PASSWORD=“cvander<3” export PLATZI_DB_PORT=“5432” export PLATZI_DB_HOST=“localhost” export DJANGO_SETTINGS_MODULE=“platzi.settings.prod” export PYTHONPATH=$DJANGODIR:$PYTHONPATH exec gunicorn ${DJANGO_WSGI_MODULE} \ --workers $NUM_WORKERS \ --user=$USER --group=$GROUP \ --log-level=debug \ --bind=127.0.0.1:8000 [/shell]
  4. Hacer el script ejecutable: [shell]chmod +x deploy/gunicorn_start[/shell]
  5. Probar el script: [shell]deploy/gunicorn_start[/shell]

Mientras el script esté corriendo, el proyecto estará viviendo en la IP en el puerto 80.

Crear un servicio

  1. Iniciar sesión como super usuario: [shell]sudo su -[/shell]
  2. Ir al directorio de los servicios: [shell]cd /etc/init[/shell]
  3. Crear el servicio: [shell]vim platzi.conf[/shell] Con el siguiente contenido: [shell] # platzi# description “Platzi Linux Service” # authon "Pablo Trinidad"start on startupscript exec /home/platzi/deploy/gunicorn_start end script[/shell]
  4. Iniciar servicio: [shell]service platzi start[/shell]

Por último tenemos que regresar al folder de la carpeta que contiene el proyecto y ejecutar: [shell]./manage.py collectstatic[/shell] Recuerda que el contenido de este post es complemento a una clase gratuita disponible en Comunidad Platzi. Con Platzi tú también puedes aprender, empieza con nuestra ruta de cursos de aws.

Pablo
Pablo
______pablo

835Puntos

hace 8 años

Todas sus entradas
Escribe tu comentario
+ 2
1
7861Puntos

Gracias Pablo, buen post
extraño tus cursos de django, las que tenias, eran buenismas
Espero puedas realizar nuevamente el curso actualizado de django.

0

Pablo, eso es un culo de complicado y enmarañado. Porque no nos enseñas algo mas simple. Yo solo quiero subir un proyectito de prueba para que lo vean mis clientes con solo 80 registros a lo mas, si ,… solo 70 u 80 registros

1
7517Puntos
5 años

Hola sabes que existen instancias más sencillas para subir tu proyecto de django a AWS y poder mostrarlo en línea. Si necesitas apoyo escribe @gventuraAG en Twitter.