In deze zelfstudie nemen we een eenvoudig lokaal Django-project, ondersteund door een MySQL-database, en converteren we dit om op Heroku te draaien. Amazon S3 zal worden gebruikt om onze statische bestanden te hosten, terwijl Fabric het implementatieproces zal automatiseren.
Het Project is een eenvoudig berichtensysteem. Het kan een todo-app zijn of een blog of zelfs een Twitter-kloon. Om een real-live scenario te simuleren, wordt het project eerst gemaakt met een MySQL-backend en vervolgens geconverteerd naar Postgres voor implementatie op Heroku. Ik heb persoonlijk vijf of zes projecten gehad waarbij ik precies dit moest doen:een lokaal project, ondersteund met MySQL, converteren naar een live-app op Heroku.
Instellen
Vereisten
- Lees de officiële Django Snelstartgids op Heroku. Lees het maar. Dit zal je helpen een idee te krijgen van wat we in deze tutorial zullen bereiken. We gebruiken de officiële tutorial als een gids voor ons eigen, meer geavanceerde implementatieproces.
- Maak een AWS-account en stel een actieve S3-bucket in.
- Installeer MySQL.
Laten we beginnen
Begin met het downloaden van het testproject hier, pak het uit en activeer vervolgens een virtualenv:
$ cd django_heroku_deploy
$ virtualenv --no-site-packages myenv
$ source myenv/bin/activate
Maak een nieuwe repository op Github:
$ curl -u 'USER' https://api.github.com/user/repos -d '{"name":"REPO"}'
Zorg ervoor dat u de hoofdletters KEYWORDS vervangt door uw eigen instellingen. Bijvoorbeeld:
curl -u 'mjhea0' https://api.github.com/user/repos -d '{"name":"django-deploy-heroku-s3"}'
Voeg een leesmij-bestand toe, initialiseer de lokale Git-repo en PUSH de lokale kopie naar 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
Zorg ervoor dat u de URL wijzigt in de URL van uw opslagplaats die u in de vorige stap heeft gemaakt.
Stel een nieuwe MySQL-database in met de naam 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
Update settings.py :
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_deploy',
'USER': 'root',
'PASSWORD': 'your_password',
}
}
Installeer de afhankelijkheden:
$ pip install -r requirements.txt
$ python manage.py syncdb
$ python manage.py runserver
Voer de server uit op http://localhost:8000/admin/ en zorg ervoor dat u zich kunt aanmelden bij de beheerder. Voeg een paar items toe aan de Whatever
voorwerp. Dood de server.
Converteren van MySQL naar Postgres
Opmerking: Laten we in deze hypothetische situatie doen alsof u al een tijdje aan dit project werkt met MySQL en dat u het nu naar Postgres wilt converteren.
Afhankelijkheden installeren:
$ pip install psycopg2
$ pip install py-mysql2pgsql
Een Postgres-database opzetten:
$ psql -h localhost
psql (9.2.4)
Type "help" for help.
michaelherman=# CREATE DATABASE django_deploy;
CREATE DATABASE
michaelherman=# \q
Gegevens migreren:
$ py-mysql2pgsql
Deze opdracht maakt een bestand aan met de naam mysql2pgsql.yml , met de volgende informatie:
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
Werk dit bij voor uw configuratie. Dit voorbeeld behandelt alleen de basisconversie. U kunt ook bepaalde tabellen opnemen of uitsluiten. Bekijk hier het volledige voorbeeld.
Breng de gegevens over:
$ py-mysql2pgsql -v -f mysql2pgsql.yml
Zodra de gegevens zijn overgedragen, moet u uw settings.py bijwerken bestand:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"NAME": "your_database_name",
"USER": "foo",
"PASSWORD": "bar",
"HOST": "localhost",
"PORT": "5432",
}
}
Synchroniseer ten slotte de database opnieuw, voer de testserver uit en voeg een ander item toe aan de database om ervoor te zorgen dat de conversie is geslaagd.
Voeg een local_settings.py-bestand toe
Door een local_settings.py . toe te voegen bestand, kunt u de settings.py bestand met instellingen die relevant zijn voor uw lokale omgeving, terwijl de belangrijkste settings.py bestand wordt uitsluitend gebruikt voor uw staging- en productieomgevingen.
Zorg ervoor dat u local_settings.py . toevoegt naar je .gitignore bestand om het bestand uit uw repositories te houden. Degenen die uw project willen gebruiken of eraan willen bijdragen, kunnen vervolgens de repo klonen en hun eigen local_settings.py maken bestand dat specifiek is voor hun eigen lokale omgeving.
Hoewel deze methode om twee instellingenbestanden te gebruiken al een aantal jaren gebruikelijk is, gebruiken veel Python-ontwikkelaars nu een ander patroon genaamd The One True Way. Mogelijk bekijken we dit patroon in een toekomstige tutorial.
Instellingen.py bijwerken
We moeten drie wijzigingen aanbrengen in onze huidige settings.py bestand:
Wijzig DEBUG
mode op false:
DEBUG = False
Voeg de volgende code toe aan de onderkant van het bestand:
# 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
Update de database-instellingen:
# we only need the engine name, as heroku takes care of the rest
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
}
}
Maak uw local_settings.py bestand:
$ touch local_settings.py
$ pip install dj_database_url
Voeg vervolgens de volgende code toe:
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",
}
}
Start de testserver om te controleren of alles nog werkt. Voeg nog een paar records toe aan de database.
Heroku-configuratie
Voeg een profiel toe aan de hoofdmap:
$ touch Procfile
en voeg de volgende code toe aan het bestand:
web: python manage.py runserver 0.0.0.0:$PORT --noreload
Installeer de Heroku toolbelt:
$ pip install django-toolbelt
Bevries de afhankelijkheden:
$ pip freeze > requirements.txt
Update de wsgi.py bestand:
from django.core.wsgi import get_wsgi_application
from dj_static import Cling
application = Cling(get_wsgi_application())
Test je Heroku-instellingen lokaal:
$ foreman start
Navigeer naar http://localhost:5000/.
Ziet er goed uit? Laten we Amazon S3 aan de gang krijgen.
Amazon S3
Hoewel het hypothetisch mogelijk is om statische bestanden in uw Heroku-repo te hosten, kunt u het beste een externe host gebruiken, vooral als u een klantgerichte toepassing heeft. S3 is gemakkelijk te gebruiken en vereist slechts een paar wijzigingen in uw settings.py bestand.
Afhankelijkheden installeren:
$ pip install django-storages
$ pip install boto
storages
toevoegen en boto
naar uw INSTALLED_APPS
in "settings.py"
Voeg de volgende code toe aan de onderkant van "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
De omgevingsafhankelijke instellingen van de AWS worden opgeslagen als omgevingsvariabelen. We hoeven deze dus niet elke keer dat we de ontwikkelserver uitvoeren vanaf de terminal in te stellen, we kunnen deze instellen in onze virtualenv activate
script. Pak de AWS-bucketnaam, toegangssleutel-ID en geheime toegangssleutel van S3. Open myenv/bin/activate
en voeg de volgende code toe (zorg ervoor dat u uw specifieke informatie toevoegt die u zojuist uit S3) hebt gehaald:
# S3 deployment info
export AWS_STORAGE_BUCKET_NAME=[YOUR AWS S3 BUCKET NAME]
export AWS_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXX
export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXX
Deactiveer en activeer uw virtualenv en start vervolgens de lokale server om ervoor te zorgen dat de wijzigingen van kracht worden:
$ foreman start
Dood de server en update vervolgens de requirements.txt bestand:
$ pip freeze > requirements.txt
Push naar Github en Heroku
Laten we een back-up maken van onze bestanden naar Github voordat we naar Heroku PUSHEN:
$ git add .
$ git commit -m "update project for heroku and S3"
$ git push -u origin master
Maak een Heroku-project/repo:
$ heroku create <name>
Noem het zoals je wilt.
PUSH naar Heroku:
$ git push heroku master
Stuur de AWS-omgevingsvariabelen naar 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
Verzamel de statische bestanden en stuur ze naar Amazon:
$ heroku run python manage.py collectstatic
Ontwikkelingsdatabase toevoegen:
$ 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
Synchroniseer nu de DB:
$ heroku run python manage.py syncdb
Gegevensoverdracht
We moeten de gegevens van de lokale database naar de productiedatabase overbrengen.
Installeer de Heroku PGBackups-add-on:
$ heroku addons:add pgbackups
Dump uw lokale database:
$ pg_dump -h localhost -Fc library > db.dump
Om Heroku toegang te geven tot db dump, moet je het ergens naar internet uploaden. U kunt een persoonlijke website, dropbox of S3 gebruiken. Ik heb het gewoon geüpload naar de S3-bucket.
Importeer de dump naar Heroku:
$ heroku pgbackups:restore DATABASE http://www.example.com/db.dump
Test
Laten we testen of alles werkt.
Werk eerst uw toegestane hosts bij naar uw specifieke domein in settings.py :
ALLOWED_HOSTS = ['[your-project-name].herokuapp.com']
Bekijk je app:
$ heroku open
Stof
Fabric wordt gebruikt voor het automatiseren van de implementatie van uw applicatie.
Installeren:
$ pip install fabric
Maak het fabbestand:
$ touch fabfile.py
Voeg vervolgens de volgende code toe:
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
Heeft u vragen of opmerkingen? Neem deel aan de onderstaande discussie.