sql >> Base de Datos >  >> RDS >> Database

Migrando tu Proyecto Django a Heroku

En este tutorial, tomaremos un proyecto Django local simple, respaldado por una base de datos MySQL, y lo convertiremos para que se ejecute en Heroku. Amazon S3 se utilizará para alojar nuestros archivos estáticos, mientras que Fabric automatizará el proceso de implementación.

El Proyecto es un sistema de mensajes simple. Podría ser una aplicación de tareas pendientes o un blog o incluso un clon de Twitter. Para simular un escenario real, el proyecto primero se creará con un backend de MySQL y luego se convertirá a Postgres para su implementación en Heroku. Personalmente, tuve cinco o seis proyectos en los que tuve que hacer exactamente esto:convertir un proyecto local, respaldado con MySQL, en una aplicación activa en Heroku.


Configuración


Requisitos previos

  1. Lea la guía oficial de inicio rápido de Django en Heroku. Solo leelo. Esto le ayudará a tener una idea de lo que lograremos en este tutorial. Usaremos el tutorial oficial como guía para nuestro propio proceso de implementación más avanzado.
  2. Cree una cuenta de AWS y configure un depósito S3 activo.
  3. Instalar MySQL.


Empecemos

Comience por descargar el proyecto de prueba aquí, descomprímalo y luego active un entorno virtual:

$ cd django_heroku_deploy
$ virtualenv --no-site-packages myenv
$ source myenv/bin/activate

Crea un nuevo repositorio en Github:

$ curl -u 'USER' https://api.github.com/user/repos -d '{"name":"REPO"}'

Asegúrese de reemplazar las PALABRAS CLAVE en mayúsculas con su propia configuración. Por ejemplo:curl -u 'mjhea0' https://api.github.com/user/repos -d '{"name":"django-deploy-heroku-s3"}'

Agregue un archivo Léame, inicialice el repositorio local de Git, luego EMPUJE la copia local a Github:

$ touch README.md
$ git init
$ git add .
$ git commit -am "initial"
$ git remote add origin https://github.com/username/Hello-World.git
$ git push origin master

Asegúrese de cambiar la URL a la URL de su repositorio que creó en el paso anterior.

Configure una nueva base de datos MySQL llamada django_deploy :

$ mysql.server start
$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g. Your MySQL connection id is 1
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql>
mysql> CREATE DATABASE django_deploy;
Query OK, 1 row affected (0.01 sec)
mysql>
mysql> quit
Bye

Actualizar settings.py :

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_deploy',
        'USER': 'root',
        'PASSWORD': 'your_password',
    }
}

Instale las dependencias:

$ pip install -r requirements.txt
$ python manage.py syncdb
$ python manage.py runserver

Ejecute el servidor en http://localhost:8000/admin/ y asegúrese de que puede iniciar sesión en el administrador. Agregue algunos elementos a Whatever objeto. Mata al servidor.




Convertir de MySQL a Postgres

Nota: En esta situación hipotética, supongamos que ha estado trabajando en este proyecto durante un tiempo usando MySQL y ahora desea convertirlo a Postgres.

Instalar dependencias:

$ pip install psycopg2
$ pip install py-mysql2pgsql

Configure una base de datos de Postgres:

$ psql -h localhost
psql (9.2.4)
Type "help" for help.
michaelherman=# CREATE DATABASE django_deploy;
CREATE DATABASE
michaelherman=# \q

Migrar datos:

$ py-mysql2pgsql

Este comando crea un archivo llamado mysql2pgsql.yml , que contiene la siguiente información:

mysql:
  hostname: localhost
  port: 3306
  socket: /tmp/mysql.sock
  username: foo
  password: bar
  database: your_database_name
  compress: false
destination:
  postgres:
    hostname: localhost
    port: 5432
    username: foo
    password: bar
    database: your_database_name

Actualice esto para su configuración. Este ejemplo solo cubre la conversión básica. También puede incluir o excluir ciertas tablas. Vea el ejemplo completo aquí.

Transferir los datos:

$ py-mysql2pgsql -v -f mysql2pgsql.yml

Una vez que se transfieran los datos, asegúrese de actualizar su settings.py archivo:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql_psycopg2",
        "NAME": "your_database_name",
        "USER": "foo",
        "PASSWORD": "bar",
        "HOST": "localhost",
        "PORT": "5432",
    }
}

Finalmente, vuelva a sincronizar la base de datos, ejecute el servidor de prueba y agregue otro elemento a la base de datos para asegurarse de que la conversión se realizó correctamente.



Agregue un archivo local_settings.py

Agregando un local_settings.py archivo, puede extender el settings.py archivo con la configuración relevante para su entorno local, mientras que el principal settings.py El archivo se utiliza únicamente para sus entornos de ensayo y producción.

Asegúrese de agregar local_settings.py a tu .gitignore archivo para mantener el archivo fuera de sus repositorios. Aquellos que quieran usar o contribuir con su proyecto pueden clonar el repositorio y crear su propio local_settings.py archivo específico para su propio entorno local.

Aunque este método de usar dos archivos de configuración ha sido convencional durante varios años, muchos desarrolladores de Python ahora usan otro patrón llamado The One True Way. Es posible que veamos este patrón en un tutorial futuro.


Actualizar configuración.py

Necesitamos hacer tres cambios en nuestro settings.py actual archivo:

Cambiar DEBUG modo a falso:

DEBUG = False

Agregue el siguiente código al final del archivo:

# Allow all host hosts/domain names for this site
ALLOWED_HOSTS = ['*']

# Parse database configuration from $DATABASE_URL
import dj_database_url

DATABASES = { 'default' : dj_database_url.config()}

# Honor the 'X-Forwarded-Proto' header for request.is_secure()
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

# try to load local_settings.py if it exists
try:
  from local_settings import *
except Exception as e:
  pass

Actualice la configuración de la base de datos:

# we only need the engine name, as heroku takes care of the rest
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql_psycopg2",
    }
}

Cree su local_settings.py archivo:

$ touch local_settings.py
$ pip install dj_database_url

Luego agregue el siguiente código:

from settings import PROJECT_ROOT, SITE_ROOT
import os

DEBUG = True
TEMPLATE_DEBUG = True

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql_psycopg2",
        "NAME": "django_deploy",
        "USER": "foo",
        "PASSWORD": "bar",
        "HOST": "localhost",
        "PORT": "5432",
    }
}

Encienda el servidor de prueba para asegurarse de que todo sigue funcionando. Agregue algunos registros más a la base de datos.




Configuración de Heroku

Agregue un Procfile al directorio principal:

$ touch Procfile

y agregue el siguiente código al archivo:

web: python manage.py runserver 0.0.0.0:$PORT --noreload

Instale el cinturón de herramientas de Heroku:

$ pip install django-toolbelt

Congelar las dependencias:

$ pip freeze > requirements.txt

Actualice wsgi.py archivo:

from django.core.wsgi import get_wsgi_application
from dj_static import Cling

application = Cling(get_wsgi_application())

Pruebe su configuración de Heroku localmente:

$ foreman start

Navegue a http://localhost:5000/.

¿Luciendo bien? Hagamos funcionar Amazon S3.



Amazon S3

Aunque hipotéticamente es posible alojar archivos estáticos en su repositorio de Heroku, es mejor utilizar un host de terceros, especialmente si tiene una aplicación orientada al cliente. S3 es fácil de usar y solo requiere unos pocos cambios en su settings.py archivo.

Instalar dependencias:

$ pip install django-storages
$ pip install boto

Agregar storages y boto a tus INSTALLED_APPS en "configuraciones.py"

Agregue el siguiente código al final de "settings.py":

# Storage on S3 settings are stored as os.environs to keep settings.py clean
if not DEBUG:
   AWS_STORAGE_BUCKET_NAME = os.environ['AWS_STORAGE_BUCKET_NAME']
   AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID']
   AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
   STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
   S3_URL = 'http://%s.s3.amazonaws.com/' % AWS_STORAGE_BUCKET_NAME
   STATIC_URL = S3_URL

La configuración dependiente del entorno de AWS se almacena como variables ambientales. Así que no tenemos que configurarlos desde la terminal cada vez que ejecutamos el servidor de desarrollo, podemos configurarlos en nuestro virtualenv activate texto. Tome el nombre del depósito de AWS, el ID de la clave de acceso y la clave de acceso secreta de S3. Abra myenv/bin/activate y agregue el siguiente código (asegúrese de agregar su información específica que acaba de obtener de S3):

# S3 deployment info
export AWS_STORAGE_BUCKET_NAME=[YOUR AWS S3 BUCKET NAME]
export AWS_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXX
export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXX

Desactive y reactive su virtualenv, luego inicie el servidor local para asegurarse de que los cambios surtieron efecto:

$ foreman start

Elimine el servidor, luego actualice requirements.txt archivo:

$ pip freeze > requirements.txt


Enviar a Github y Heroku

Hagamos una copia de seguridad de nuestros archivos en Github antes de enviarlos a Heroku:

$ git add .
$ git commit -m "update project for heroku and S3"
$ git push -u origin master

Crear un proyecto/repositorio de Heroku:

$ heroku create <name>

Nómbralo como quieras.

EMPUJAR a Heroku:

$ git push heroku master

Envía las variables ambientales de AWS a Heroku

$ heroku config:set AWS_STORAGE_BUCKET_NAME=[YOUR AWS S3 BUCKET NAME]
$ heroku config:set AWS_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXX
$ heroku config:set AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXX

Recopile los archivos estáticos y envíelos a Amazon:

$ heroku run python manage.py collectstatic

Agregar base de datos de desarrollo:

$ heroku addons:add heroku-postgresql:dev
Adding heroku-postgresql on deploy_django... done, v13 (free)
Attached as HEROKU_POSTGRESQL_COPPER_URL
Database has been created and is available
! This database is empty. If upgrading, you can transfer
! data from another database with pgbackups:restore.
Use `heroku addons:docs heroku-postgresql` to view documentation.
$ heroku pg:promote HEROKU_POSTGRESQL_COPPER_URL
Promoting HEROKU_POSTGRESQL_COPPER_URL to DATABASE_URL... done

Ahora sincroniza la base de datos:

$ heroku run python manage.py syncdb


Transferencia de datos

Necesitamos transferir los datos de la base de datos local a la base de datos de producción.

Instale el complemento Heroku PGBackups:

$ heroku addons:add pgbackups

Volcar su base de datos local:

$ pg_dump -h localhost  -Fc library  > db.dump

Para que Heroku acceda al volcado de db, debe cargarlo en Internet en algún lugar. Puede usar un sitio web personal, Dropbox o S3. Simplemente lo cargué en el depósito S3.

Importar el volcado a Heroku:

$ heroku pgbackups:restore DATABASE http://www.example.com/db.dump


Prueba

Probemos para asegurarnos de que todo funciona.

Primero, actualice sus hosts permitidos a su dominio específico en settings.py :

ALLOWED_HOSTS = ['[your-project-name].herokuapp.com']

Echa un vistazo a tu aplicación:

$ heroku open


Tela

Fabric se utiliza para automatizar la implementación de su aplicación.

Instalar:

$ pip install fabric

Crea el archivo fab:

$ touch fabfile.py

Luego agregue el siguiente código:

from fabric.api import local

def deploy():
   local('pip freeze > requirements.txt')
   local('git add .')
   print("enter your git commit comment: ")
   comment = raw_input()
   local('git commit -m "%s"' % comment)
   local('git push -u origin master')
   local('heroku maintenance:on')
   local('git push heroku master')
   local('heroku maintenance:off')

Prueba:

$ fab deploy

¿Tiene preguntas o comentarios? Únase a la discusión a continuación.