Database
 sql >> Database >  >> RDS >> Database

Migrazione del tuo progetto Django su Heroku

In questo tutorial, prenderemo un semplice progetto Django locale, supportato da un database MySQL, e lo convertiremo per eseguirlo su Heroku. Amazon S3 verrà utilizzato per ospitare i nostri file statici, mentre Fabric automatizza il processo di distribuzione.

Il Progetto è un semplice sistema di messaggi. Potrebbe essere un'app di cose da fare o un blog o persino un clone di Twitter. Per simulare uno scenario dal vivo, il progetto verrà prima creato con un backend MySQL, quindi convertito in Postgres per l'implementazione su Heroku. Personalmente ho avuto cinque o sei progetti in cui ho dovuto fare esattamente questa cosa:convertire un progetto locale, supportato da MySQL, in un'app live su Heroku.


Configurazione


Prerequisiti

  1. Leggi la guida ufficiale di Django Quick Start su Heroku. Basta leggerlo. Questo ti aiuterà a farti un'idea di ciò che realizzeremo in questo tutorial. Utilizzeremo il tutorial ufficiale come guida per il nostro processo di implementazione più avanzato.
  2. Crea un account AWS e configura un bucket S3 attivo.
  3. Installa MySQL.


Iniziamo

Inizia scaricando il progetto di prova qui, decomprimi, quindi attiva un virtualenv:

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

Crea un nuovo repository su Github:

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

Assicurati di sostituire le PAROLE CHIAVE in maiuscolo con le tue impostazioni. Ad esempio:curl -u 'mjhea0' https://api.github.com/user/repos -d '{"name":"django-deploy-heroku-s3"}'

Aggiungi un file readme, inizializza il repository Git locale, quindi PUSH la copia locale su 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

Assicurati di cambiare l'URL con l'URL del tuo repository che hai creato nel passaggio precedente.

Configura un nuovo database MySQL chiamato 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

Aggiorna settings.py :

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

Installa le dipendenze:

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

Esegui il server su http://localhost:8000/admin/ e assicurati di poter accedere all'amministratore. Aggiungi alcuni elementi a Whatever oggetto. Uccidi il server.




Converti da MySQL a Postgres

Nota: In questa ipotetica situazione, supponiamo che tu stia lavorando a questo progetto per un po' di tempo usando MySQL e ora desideri convertirlo in Postgres.

Installa le dipendenze:

$ pip install psycopg2
$ pip install py-mysql2pgsql

Configura un database Postgres:

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

Migrare i dati:

$ py-mysql2pgsql

Questo comando crea un file chiamato mysql2pgsql.yml , contenente le seguenti informazioni:

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

Aggiornalo per la tua configurazione. Questo esempio copre solo la conversione di base. Puoi anche includere o escludere determinate tabelle. Vedi l'esempio completo qui.

Trasferisci i dati:

$ py-mysql2pgsql -v -f mysql2pgsql.yml

Una volta trasferiti i dati, assicurati di aggiornare il tuo settings.py file:

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

Infine, risincronizza il database, esegui il server di prova e aggiungi un altro elemento al database per assicurarti che la conversione sia riuscita.



Aggiungi un file local_settings.py

Aggiungendo un local_settings.py puoi estendere il file settings.py file con le impostazioni rilevanti per il tuo ambiente locale, mentre il principale settings.py viene utilizzato esclusivamente per i tuoi ambienti di staging e produzione.

Assicurati di aggiungere local_settings.py al tuo .gitignore file per mantenere il file fuori dai tuoi repository. Coloro che desiderano utilizzare o contribuire al tuo progetto possono quindi clonare il repository e creare il proprio local_settings.py file specifico per il proprio ambiente locale.

Sebbene questo metodo di utilizzo di due file di impostazioni sia una convenzione da diversi anni, molti sviluppatori Python ora utilizzano un altro modello chiamato The One True Way. Potremmo esaminare questo modello in un tutorial futuro.


Aggiorna settings.py

Dobbiamo apportare tre modifiche al nostro attuale settings.py file:

Modifica DEBUG modalità su falso:

DEBUG = False

Aggiungi il codice seguente in fondo al file:

# 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

Aggiorna le impostazioni del database:

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

Crea il tuo local_settings.py file:

$ touch local_settings.py
$ pip install dj_database_url

Quindi aggiungi il seguente codice:

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",
    }
}

Avvia il server di prova per assicurarti che tutto funzioni ancora. Aggiungi qualche altro record al database.




Impostazione Heroku

Aggiungi un Procfile alla directory principale:

$ touch Procfile

e aggiungi il seguente codice al file:

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

Installa la cintura degli strumenti Heroku:

$ pip install django-toolbelt

Blocca le dipendenze:

$ pip freeze > requirements.txt

Aggiorna wsgi.py file:

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

application = Cling(get_wsgi_application())

Testa le impostazioni di Heroku in locale:

$ foreman start

Vai a http://localhost:5000/.

Stai bene? Facciamo funzionare Amazon S3.



Amazon S3

Sebbene sia ipoteticamente possibile ospitare file statici nel repository Heroku, è meglio utilizzare un host di terze parti, soprattutto se si dispone di un'applicazione rivolta al cliente. S3 è facile da usare e richiede solo poche modifiche al tuo settings.py file.

Installa le dipendenze:

$ pip install django-storages
$ pip install boto

Aggiungi storages e boto al tuo INSTALLED_APPS in "impostazioni.py"

Aggiungi il seguente codice in fondo a "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

Le impostazioni dipendenti dall'ambiente AWS vengono archiviate come variabili ambientali. Quindi non dobbiamo impostarli dal terminale ogni volta che eseguiamo il server di sviluppo, possiamo impostarli nel nostro virtualenv activate sceneggiatura. Prendi il nome del bucket AWS, l'ID chiave di accesso e la chiave di accesso segreta da S3. Apri myenv/bin/activate e aggiungi il seguente codice (assicurati di aggiungere le informazioni specifiche che hai appena estratto da 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

Disattiva e riattiva il tuo virtualenv, quindi avvia il server locale per assicurarti che le modifiche abbiano effetto:

$ foreman start

Uccidi il server, quindi aggiorna il requirements.txt file:

$ pip freeze > requirements.txt


Spingi su Github e Heroku

Eseguiamo il backup dei nostri file su Github prima di PUSH su Heroku:

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

Crea un progetto/repo di Heroku:

$ heroku create <name>

Chiamalo come preferisci.

PUSH a Heroku:

$ git push heroku master

Invia le variabili ambientali 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

Raccogli i file statici e inviali ad Amazon:

$ heroku run python manage.py collectstatic

Aggiungi database di sviluppo:

$ 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

Ora sincronizza il DB:

$ heroku run python manage.py syncdb


Trasferimento dati

Dobbiamo trasferire i dati dal database locale al database di produzione.

Installa il componente aggiuntivo Heroku PGBackups:

$ heroku addons:add pgbackups

Scarica il tuo database locale:

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

Affinché Heroku possa accedere a db dump, devi caricarlo su Internet da qualche parte. Puoi utilizzare un sito Web personale, una casella personale o S3. L'ho semplicemente caricato nel bucket S3.

Importa il dump in Heroku:

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


Test

Proviamo per assicurarci che tutto funzioni.

Innanzitutto, aggiorna gli host consentiti al tuo dominio specifico in settings.py :

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

Dai un'occhiata alla tua app:

$ heroku open


Tessuto

Fabric viene utilizzato per automatizzare la distribuzione della tua applicazione.

Installa:

$ pip install fabric

Crea il fabfile:

$ touch fabfile.py

Quindi aggiungi il seguente codice:

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')

Prova:

$ fab deploy

Hai domande o commenti? Partecipa alla discussione qui sotto.