Database
 sql >> Base de Dados >  >> RDS >> Database

Migrando seu projeto Django para Heroku


Neste tutorial, vamos pegar um projeto Django local simples, apoiado por um banco de dados MySQL, e convertê-lo para rodar no Heroku. O Amazon S3 será usado para hospedar nossos arquivos estáticos, enquanto o Fabric automatizará o processo de implantação.

O Projeto é um sistema de mensagens simples. Pode ser um aplicativo de tarefas ou um blog ou até mesmo um clone do Twitter. Para simular um cenário real, o projeto será criado primeiro com um backend MySQL e depois convertido em Postgres para implantação no Heroku. Eu pessoalmente tive cinco ou seis projetos em que tive que fazer exatamente isso:converter um projeto local, apoiado com MySQL, em um aplicativo ao vivo no Heroku.

Configuração


Pré-requisitos

  1. Leia o guia oficial do Django Quick Start no Heroku. Basta lê-lo. Isso ajudará você a ter uma ideia do que realizaremos neste tutorial. Usaremos o tutorial oficial como um guia para nosso próprio processo de implantação mais avançado.
  2. Crie uma conta da AWS e configure um bucket S3 ativo.
  3. Instale o MySQL.


Vamos começar


Comece baixando o projeto de teste aqui, descompacte e ative um virtualenv:
$ cd django_heroku_deploy
$ virtualenv --no-site-packages myenv
$ source myenv/bin/activate

Crie um novo repositório no Github:
$ curl -u 'USER' https://api.github.com/user/repos -d '{"name":"REPO"}'

Certifique-se de substituir todas as PALAVRAS-CHAVE em maiúsculas por suas próprias configurações. Por exemplo:curl -u 'mjhea0' https://api.github.com/user/repos -d '{"name":"django-deploy-heroku-s3"}'

Adicione um arquivo leia-me, inicialize o repositório Git local e, em seguida, PUSH a cópia local para o 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

Certifique-se de alterar o URL para o URL do seu repositório que você criou na etapa anterior.

Configure um novo banco de dados MySQL chamado 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

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

Instale as dependências:
$ pip install -r requirements.txt
$ python manage.py syncdb
$ python manage.py runserver

Execute o servidor em http://localhost:8000/admin/ e certifique-se de que consegue fazer login no admin. Adicione alguns itens ao Whatever objeto. Mate o servidor.



Converter do MySQL para Postgres


Observação: Nesta situação hipotética, vamos fingir que você está trabalhando neste projeto há algum tempo usando MySQL e agora deseja convertê-lo para Postgres.

Instalar dependências:
$ pip install psycopg2
$ pip install py-mysql2pgsql

Configure um banco de dados Postgres:
$ psql -h localhost
psql (9.2.4)
Type "help" for help.
michaelherman=# CREATE DATABASE django_deploy;
CREATE DATABASE
michaelherman=# \q

Migrar dados:
$ py-mysql2pgsql

Este comando cria um arquivo chamado mysql2pgsql.yml , contendo as seguintes informações:
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

Atualize isso para sua configuração. Este exemplo cobre apenas a conversão básica. Você também pode incluir ou excluir determinadas tabelas. Veja o exemplo completo aqui.

Transfira os dados:
$ py-mysql2pgsql -v -f mysql2pgsql.yml

Depois que os dados forem transferidos, certifique-se de atualizar seu settings.py Arquivo:
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql_psycopg2",
        "NAME": "your_database_name",
        "USER": "foo",
        "PASSWORD": "bar",
        "HOST": "localhost",
        "PORT": "5432",
    }
}

Por fim, sincronize novamente o banco de dados, execute o servidor de teste e adicione outro item ao banco de dados para garantir que a conversão seja bem-sucedida.


Adicione um arquivo local_settings.py


Ao adicionar um local_settings.py arquivo, você pode estender o arquivo settings.py arquivo com configurações relevantes para seu ambiente local, enquanto o arquivo principal settings.py arquivo é usado exclusivamente para seus ambientes de preparação e produção.

Certifique-se de adicionar local_settings.py para o seu .gitignore file para manter o arquivo fora de seus repositórios. Aqueles que desejam usar ou contribuir com seu projeto podem clonar o repositório e criar seu próprio local_settings.py arquivo específico para seu próprio ambiente local.

Embora esse método de usar dois arquivos de configuração seja uma convenção há vários anos, muitos desenvolvedores de Python agora usam outro padrão chamado The One True Way. Podemos olhar para este padrão em um tutorial futuro.

Atualizar settings.py


Precisamos fazer três alterações em nosso settings.py atual Arquivo:

Alterar DEBUG modo para falso:
DEBUG = False

Adicione o seguinte código ao final do arquivo:
# 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

Atualize as configurações do banco de dados:
# we only need the engine name, as heroku takes care of the rest
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql_psycopg2",
    }
}

Crie seu local_settings.py Arquivo:
$ touch local_settings.py
$ pip install dj_database_url

Em seguida, adicione o seguinte 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",
    }
}

Inicie o servidor de teste para garantir que tudo ainda funcione. Adicione mais alguns registros ao banco de dados.



Configuração do Heroku


Adicione um Procfile ao diretório principal:
$ touch Procfile

e adicione o seguinte código ao arquivo:
web: python manage.py runserver 0.0.0.0:$PORT --noreload

Instale o cinto de ferramentas Heroku:
$ pip install django-toolbelt

Congele as dependências:
$ pip freeze > requirements.txt

Atualize o wsgi.py Arquivo:
from django.core.wsgi import get_wsgi_application
from dj_static import Cling

application = Cling(get_wsgi_application())

Teste suas configurações do Heroku localmente:
$ foreman start

Navegue até http://localhost:5000/.

Parece bom? Vamos colocar o Amazon S3 em execução.


Amazon S3


Embora seja hipoteticamente possível hospedar arquivos estáticos em seu repositório Heroku, é melhor usar um host de terceiros, especialmente se você tiver um aplicativo voltado para o cliente. O S3 é fácil de usar e requer apenas algumas alterações em seu settings.py Arquivo.

Instalar dependências:
$ pip install django-storages
$ pip install boto

Adicionar storages e boto para seu INSTALLED_APPS em “configurações.py”

Adicione o seguinte código ao 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

As configurações dependentes do ambiente da AWS são armazenadas como variáveis ​​ambientais. Portanto, não precisamos configurá-los no terminal toda vez que executamos o servidor de desenvolvimento, podemos configurá-los em nosso virtualenv activate roteiro. Obtenha o nome do AWS Bucket, o ID da chave de acesso e a chave de acesso secreta do S3. Abra myenv/bin/activate e anexe o seguinte código (certifique-se de adicionar suas informações específicas que você acabou de extrair do 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

Desative e reative seu virtualenv e, em seguida, inicie o servidor local para garantir que as alterações tenham efeito:
$ foreman start

Mate o servidor e atualize o requirements.txt Arquivo:
$ pip freeze > requirements.txt


Enviar para Github e Heroku


Vamos fazer backup de nossos arquivos no Github antes de enviar para o Heroku:
$ git add .
$ git commit -m "update project for heroku and S3"
$ git push -u origin master

Crie um projeto/repositório Heroku:
$ heroku create <name>

Dê o nome que quiser.

PUSH para Heroku:
$ git push heroku master

Envie as variáveis ​​ambientais da AWS para o 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

Colete os arquivos estáticos e envie para a Amazon:
$ heroku run python manage.py collectstatic

Adicionar banco de dados de desenvolvimento:
$ 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

Agora sincronize o banco de dados:
$ heroku run python manage.py syncdb


Transferência de dados


Precisamos transferir os dados do banco de dados local para o banco de dados de produção.

Instale o complemento Heroku PGBackups:
$ heroku addons:add pgbackups

Despeje seu banco de dados local:
$ pg_dump -h localhost  -Fc library  > db.dump

Para que o Heroku acesse o dump de banco de dados, você precisa enviá-lo para a Internet em algum lugar. Você pode usar um site pessoal, caixa de depósito ou S3. Eu simplesmente fiz o upload para o bucket do S3.

Importe o dump para o Heroku:
$ heroku pgbackups:restore DATABASE http://www.example.com/db.dump


Teste


Vamos testar para ter certeza de que tudo funciona.

Primeiro, atualize seus hosts permitidos para seu domínio específico em settings.py :
ALLOWED_HOSTS = ['[your-project-name].herokuapp.com']

Confira seu aplicativo:
$ heroku open


Tecido


O Fabric é usado para automatizar a implantação do seu aplicativo.

Instalar:
$ pip install fabric

Crie o arquivo fab:
$ touch fabfile.py

Em seguida, adicione o seguinte 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')

Teste:
$ fab deploy

Tem perguntas ou comentários? Participe da discussão abaixo.