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

Migration Ihres Django-Projekts zu Heroku

In diesem Tutorial nehmen wir ein einfaches lokales Django-Projekt, das von einer MySQL-Datenbank unterstützt wird, und konvertieren es für die Ausführung auf Heroku. Amazon S3 wird verwendet, um unsere statischen Dateien zu hosten, während Fabric den Bereitstellungsprozess automatisiert.

Das Projekt ist ein einfaches Nachrichtensystem. Es könnte eine Aufgaben-App oder ein Blog oder sogar ein Twitter-Klon sein. Um ein reales Szenario zu simulieren, wird das Projekt zunächst mit einem MySQL-Backend erstellt und dann für die Bereitstellung auf Heroku in Postgres konvertiert. Ich persönlich hatte fünf oder sechs Projekte, bei denen ich genau das tun musste:ein lokales Projekt mit MySQL-Unterstützung in eine Live-App auf Heroku umwandeln.


Einrichtung


Voraussetzungen

  1. Lesen Sie die offizielle Django-Schnellstartanleitung drüben bei Heroku. Lies es einfach. Dies wird Ihnen helfen, ein Gefühl dafür zu bekommen, was wir in diesem Tutorial erreichen werden. Wir werden das offizielle Tutorial als Leitfaden für unseren eigenen, fortgeschritteneren Bereitstellungsprozess verwenden.
  2. Erstellen Sie ein AWS-Konto und richten Sie einen aktiven S3-Bucket ein.
  3. Installieren Sie MySQL.


Fangen wir an

Laden Sie zunächst das Testprojekt hier herunter, entpacken Sie es und aktivieren Sie dann eine virtuelle Umgebung:

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

Erstellen Sie ein neues Repository auf Github:

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

Stellen Sie sicher, dass Sie alle SCHLÜSSELWÖRTER in Großbuchstaben durch Ihre eigenen Einstellungen ersetzen. Zum Beispiel:curl -u 'mjhea0' https://api.github.com/user/repos -d '{"name":"django-deploy-heroku-s3"}'

Fügen Sie eine Readme-Datei hinzu, initialisieren Sie das lokale Git-Repo und schieben Sie dann die lokale Kopie auf 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

Stellen Sie sicher, dass Sie die URL in die URL Ihres Repositorys ändern, die Sie im vorherigen Schritt erstellt haben.

Richten Sie eine neue MySQL-Datenbank namens django_deploy ein :

$ 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

Aktualisieren Sie settings.py :

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

Installieren Sie die Abhängigkeiten:

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

Führen Sie den Server unter http://localhost:8000/admin/ aus und stellen Sie sicher, dass Sie sich beim Administrator anmelden können. Fügen Sie dem Whatever ein paar Elemente hinzu Objekt. Beenden Sie den Server.




Von MySQL zu Postgres konvertieren

Hinweis: Nehmen wir in dieser hypothetischen Situation an, dass Sie eine Weile an diesem Projekt mit MySQL gearbeitet haben und es jetzt in Postgres konvertieren möchten.

Abhängigkeiten installieren:

$ pip install psycopg2
$ pip install py-mysql2pgsql

Richten Sie eine Postgres-Datenbank ein:

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

Daten migrieren:

$ py-mysql2pgsql

Dieser Befehl erstellt eine Datei namens mysql2pgsql.yml , die die folgenden Informationen enthält:

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

Aktualisieren Sie dies für Ihre Konfiguration. Dieses Beispiel behandelt nur die grundlegende Konvertierung. Sie können auch bestimmte Tabellen ein- oder ausschließen. Das vollständige Beispiel finden Sie hier.

Übertragen Sie die Daten:

$ py-mysql2pgsql -v -f mysql2pgsql.yml

Aktualisieren Sie nach der Übertragung der Daten unbedingt Ihre settings.py Datei:

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

Synchronisieren Sie schließlich die Datenbank erneut, führen Sie den Testserver aus und fügen Sie der Datenbank ein weiteres Element hinzu, um sicherzustellen, dass die Konvertierung erfolgreich war.



Fügen Sie eine local_settings.py-Datei hinzu

Durch Hinzufügen einer local_settings.py Datei können Sie die settings.py erweitern Datei mit Einstellungen, die für Ihre lokale Umgebung relevant sind, während die Hauptdatei settings.py Datei wird ausschließlich für Ihre Staging- und Produktionsumgebungen verwendet.

Stellen Sie sicher, dass Sie local_settings.py hinzufügen zu Ihrer .gitignore Datei, um die Datei aus Ihren Repositorys fernzuhalten. Diejenigen, die Ihr Projekt verwenden oder zu Ihrem Projekt beitragen möchten, können dann das Repository klonen und ihre eigene local_settings.py erstellen Datei, die für ihre eigene lokale Umgebung spezifisch ist.

Obwohl diese Methode der Verwendung von zwei Einstellungsdateien seit einigen Jahren üblich ist, verwenden viele Python-Entwickler jetzt ein anderes Muster namens The One True Way. Wir werden uns dieses Muster möglicherweise in einem zukünftigen Tutorial ansehen.


Einstellungen.py aktualisieren

Wir müssen drei Änderungen an unserer aktuellen settings.py vornehmen Datei:

Ändern Sie DEBUG Modus auf false:

DEBUG = False

Fügen Sie den folgenden Code am Ende der Datei hinzu:

# 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

Aktualisieren Sie die Datenbankeinstellungen:

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

Erstellen Sie Ihre local_settings.py Datei:

$ touch local_settings.py
$ pip install dj_database_url

Fügen Sie dann den folgenden Code hinzu:

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

Starten Sie den Testserver, um sicherzustellen, dass alles noch funktioniert. Fügen Sie der Datenbank ein paar weitere Datensätze hinzu.




Heroku-Setup

Fügen Sie dem Hauptverzeichnis eine Proc-Datei hinzu:

$ touch Procfile

und fügen Sie der Datei den folgenden Code hinzu:

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

Installieren Sie den Heroku-Toolbelt:

$ pip install django-toolbelt

Abhängigkeiten einfrieren:

$ pip freeze > requirements.txt

Aktualisieren Sie wsgi.py Datei:

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

application = Cling(get_wsgi_application())

Testen Sie Ihre Heroku-Einstellungen lokal:

$ foreman start

Navigieren Sie zu http://localhost:5000/.

Gut aussehen? Lassen Sie uns Amazon S3 zum Laufen bringen.



Amazon S3

Obwohl es hypothetisch möglich ist, statische Dateien in Ihrem Heroku-Repo zu hosten, ist es am besten, einen Drittanbieter-Host zu verwenden, insbesondere wenn Sie eine kundenorientierte Anwendung haben. S3 ist einfach zu verwenden und erfordert nur wenige Änderungen an Ihrer settings.py Datei.

Abhängigkeiten installieren:

$ pip install django-storages
$ pip install boto

Fügen Sie storages hinzu und boto zu Ihren INSTALLED_APPS in „settings.py“

Fügen Sie den folgenden Code am Ende von „settings.py“ hinzu:

# 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

Die AWS-umgebungsabhängigen Einstellungen werden als Umgebungsvariablen gespeichert. Wir müssen diese also nicht jedes Mal vom Terminal aus festlegen, wenn wir den Entwicklungsserver ausführen, wir können diese in unserer virtuellen Umgebung activate festlegen Skript. Holen Sie sich den Namen des AWS-Buckets, die Zugriffsschlüssel-ID und den geheimen Zugriffsschlüssel von S3. Öffnen Sie myenv/bin/activate und fügen Sie den folgenden Code hinzu (stellen Sie sicher, dass Sie Ihre spezifischen Informationen hinzufügen, die Sie gerade aus S3 gezogen haben):

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

Deaktivieren und reaktivieren Sie Ihre virtuelle Umgebung und starten Sie dann den lokalen Server, um sicherzustellen, dass die Änderungen wirksam werden:

$ foreman start

Beenden Sie den Server und aktualisieren Sie dann die requirements.txt Datei:

$ pip freeze > requirements.txt


Zu Github und Heroku pushen

Lassen Sie uns unsere Dateien auf Github sichern, bevor wir sie an Heroku PUSHen:

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

Erstellen Sie ein Heroku-Projekt/Repo:

$ heroku create <name>

Benennen Sie es wie Sie möchten.

PUSH zu Heroku:

$ git push heroku master

Senden Sie die AWS-Umgebungsvariablen an 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

Sammeln Sie die statischen Dateien und senden Sie sie an Amazon:

$ heroku run python manage.py collectstatic

Entwicklungsdatenbank hinzufügen:

$ 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

Synchronisieren Sie nun die DB:

$ heroku run python manage.py syncdb


Datenübertragung

Wir müssen die Daten von der lokalen Datenbank in die Produktionsdatenbank übertragen.

Installieren Sie das Heroku PGBackups-Add-on:

$ heroku addons:add pgbackups

Sichern Sie Ihre lokale Datenbank:

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

Damit Heroku auf db dump zugreifen kann, müssen Sie es irgendwo ins Internet hochladen. Sie können eine persönliche Website, Dropbox oder S3 verwenden. Ich habe es einfach in den S3-Bucket hochgeladen.

Importieren Sie den Speicherauszug in Heroku:

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


Test

Lassen Sie uns testen, ob alles funktioniert.

Aktualisieren Sie zunächst Ihre zulässigen Hosts auf Ihre spezifische Domain in settings.py :

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

Sehen Sie sich Ihre App an:

$ heroku open


Stoff

Fabric wird zur Automatisierung der Bereitstellung Ihrer Anwendung verwendet.

Installieren:

$ pip install fabric

Fabfile erstellen:

$ touch fabfile.py

Fügen Sie dann den folgenden Code hinzu:

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

Test:

$ fab deploy

Haben Sie Fragen oder Anmerkungen? Nehmen Sie an der Diskussion unten teil.