¡Despliega tu app de Django a Heroku fácil!
Published: 2020-04-29 07:48:25

¿Estás sufriendo haciendo el despliegue de tu aplicación? No te preocupes que te enseñaré cómo hacerlo, te explicaré lo mejor que pueda para que tengas esa flamante app de Django en Heroku.

¿Por qué Heroku? Es sencillo y **es gratis**.

# ¿Qué necesitas?

¿Ya te dije que ocuparemos Heroku? ¡Entonces lo primero que vas a necesitar es tener una cuenta en Heroku!

De igual manera vas a necesitar instalar Heroku CLI, te lo dejo en el siguiente link:

https://devcenter.heroku.com/articles/heroku-cli#download-and-install

¿Y qué hay de tu flamante app en Django? Si estás viendo este post es probable que ya la tengas y necesitas ayuda pero en el caso contrario, no te preocupes. Puedes ocupar mi flamante app de gatitos para hacer este tutorial. La puedes encontrar en el siguiente repositorio. 👇🏻

{% github mauricio-chavez/mishos-heroku-django no-readme %}

> De preferencia hazle un fork, no lo clones directamente.

Una vez tengas tu app de Django, necesitas tener los siguientes archivos en la raíz de tu proyecto:

* requirements.txt
* Pipfile

Si no tienes estos archivos, no te preocupes que ahorita te explicaremos para qué sirve cada uno, pero que sepas que son necesarios para que Heroku pueda identificar tu app correctamente.

## requirements.txt

En este archivo deben estar todas las dependencias de tu proyecto, por lo tanto debería estar al menos `Django`, `gunicorn` y `django-heroku`. Este archivo puede lucir más o menos de cualquiera de las siguientes formas:

```text
Django
gunicorn
django-heroku
```

```text
Django==3.0.5
gunicorn==20.0.4
django-heroku==0.3.1
```

```text
Django>=3.0.5,<3.1.0
gunicorn>=20.0.4,<20.1.0
django-heroku>=0.3.1,<0.4.0
```

Si tú estás usando otras dependencias y aún no tienes tu archivo `requirements.txt` puedes generarlo de la siguiente manera en la raíz de tu proyecto:

```command-line
$ pip freeze > requirements.txt
```

## Procfile

Como describe Heroku, este archivo es usado para declarar explícitamente los tipos de procesos en tu aplicación y sus puntos de entrada. Yo te recomiendo que luzca más o menos de la siguiente manera:

```text
release: python manage.py migrate --noinput
web: gunicorn nombre_del_proyecto.wsgi:application --log-file -
```

A través del proceso `release`, Heroku se encarga de correr lo que necesites en tiempo de despliegue. En nuestro caso concreto, de correr las migraciones.

Y es con el proceso `web` que le diremos que corra nuestra aplicación. Nosotros ocuparemos `gunicorn` para esto. Asegúrate de reemplazar `nombre_del_proyecto` por el nombre del directorio donde se encuentra la configuración de tu proyecto, por lo general con el mismo nombre que tu proyecto. En mi caso, lo reemplazaré por `mishos`.

# ¿Qué cambios debo hacer en mi código?

Lo más importante es que vamos a tener que hacer algunos cambios
en tu archivo `settings.py` para que esté preparado para producción. Antes de esto me parece necesario hablarte de algunas cosas sobre _variables de entorno_ y nuestra _base de datos_.

## Variables de entorno

En nuestro proyecto tenemos un montón de información sensible, como nuestra `SECRET_KEY`, las credenciales de nuestra base de datos, quizás alguna llave o contraseña necesaria para nuestro proyecto, etc. Por obvias razones, no podemos dejar que esa información caiga en las manos equivocadas por lo que es importante leer esta información a través de variables de entorno.

Puedes declarar una variable de entorno en tu sesión de terminal de la siguiente manera:

```command-line
$ export SECRET_KEY="llave_supersecreta"
```

Después puedes ocuparla en tu `settings.py` de la siguiente manera:

```python
SECRET_KEY = os.environ.get('SECRET_KEY')
```

Incluso puedes declarar un valor por omisión en caso de no encontrarla, por si no quieres declararla en desarrollo:

```python
SECRET_KEY = os.environ.get('SECRET_KEY', default='otra_llave_supersecreta')
```

Entonces podemos proceder a reemplazar la información sensible en nuestro código por variables de entorno. En mi caso, solo reemplazaré mi `SECRET_KEY`.

## Base de Datos

Quizás todavía estás en ocupando SQLite para tu proyecto, pero déjame te adelanto que no podrás usarla en tu aplicación en Heroku. La razón es porque es una base de datos en un documento, y por la naturaleza de un documento, no pueden escribir en el mismo múltiples usuarios, por lo que optaremos por usar Postgres en Heroku, mientras que en desarrollo puedes seguir usando SQLite. Te recomiendo encarecidamente ocupar base de datos diferentes para tus múltiples entornos de desarrollo (desarrollo y producción).

## Finalmente al código

¿Recuerdas que declaramos en nuestras dependencias que usaríamos `django-heroku`? Bueno, llegó el momento de usarla.

Importamos el paquete al inicio de `settings.py`:

```python
import django_heroku
```

Después agregamos lo siguiente al final de `settings.py`

```python
# Django-Heroku.
django_heroku.settings(locals())
```

Es importante que no haya contenido después de esto, ya que esta linea se va a encargar de preparar nuestra app para producción.

¿Qué hace esa línea exactamente? Automáticamente va a configurar tu base de datos para usar la que nos va a proveer `Heroku` a través de la variable de entorno `DATABASE_URL`, al igual que configurará nuestros `ALLOWED_HOSTS`, instalará y configurará Whitenoise para nuestros archivos estáticos, logging y Heroku CI para nuestra aplicación. **¡Incluso se encargará de leer nuestra** `SECREY_KEY` **desde una variable de entorno!**

Para más información sobre este paquete, puedes leer más en este repositorio:

{% github heroku/django-heroku no-readme %}

¡Ha llegado el momento del despliegue!

# Despliegue

Ahora es el momento de la verdad. Espero ya tengas instalado `Heroku CLI`.

Primero tendrás que iniciar sesión desde Heroku CLI desde tu terminal de la siguiente manera:

```command-line
$ heroku login
```

Una vez iniciada sesión, debes crear el app en Heroku y añadir el repositorio remoto de Heroku:

```command-line
$ heroku create nombre_de_tu_app
$ heroku git:remote -a nombre_de_tu_app
```

No olvides cambiar `nombre_de_tu_app` por el verdadero nombre.

Ahora tendrás que aprovisionar a tu app de tu base de datos `Postgres`.
```command-line
$ heroku addons:create heroku-postgresql:hobby-dev
```

Y ahora tendrás que configurar las variables de entorno necesarias, yo solo necesitaré un SECRET_KEY:

```command-line
$ heroku config:set SECRET_KEY=llave_super_secreta
```

> Este ejemplo es con fines ilustrativos, pero de ninguna manera deberías ocupar esta llave secreta o alguna similar en producción. Cámbiala por alguna llave segura. Aquí te dejo un [enlace](https://miniwebtool.com/es/django-secret-key-generator/) que te permite generarlas.

Puedes configurar varias variables de entorno a la vez:

```command-line
$ heroku config:set GITHUB_USERNAME=mauricio-chavez DEBUG=0
```

**DESPLIEGA:**

```command-line
$ git push heroku master
```

¡Disfruta de tu flamante app desplegada en Heroku!

```command-line
$ heroku open
```

La mía ya está desplegada, puedes verla en https://mishos.herokuapp.com/