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
- 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.
- Erstellen Sie ein AWS-Konto und richten Sie einen aktiven S3-Bucket ein.
- 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.