I den här handledningen tar vi ett enkelt lokalt Django-projekt, backat upp av en MySQL-databas, och konverterar det för att köras på Heroku. Amazon S3 kommer att användas som värd för våra statiska filer, medan Fabric kommer att automatisera distributionsprocessen.
Projektet är ett enkelt meddelandesystem. Det kan vara en att göra-app eller en blogg eller till och med en Twitter-klon. För att simulera ett verkligt scenario kommer projektet först att skapas med en MySQL-backend och sedan konverteras till Postgres för distribution på Heroku. Jag har personligen haft fem eller sex projekt där jag har behövt göra exakt det här:konvertera ett lokalt projekt, backat upp med MySQL, till en liveapp på Heroku.
Inställningar
Förutsättningar
- Läs den officiella Django Quick Start-guiden på Heroku. Läs den bara. Detta hjälper dig att få en känsla för vad vi kommer att åstadkomma i den här handledningen. Vi kommer att använda den officiella handledningen som en guide för vår egen, mer avancerade implementeringsprocess.
- Skapa ett AWS-konto och ställ in en aktiv S3-bucket.
- Installera MySQL.
Låt oss börja
Börja med att ladda ner testprojektet här, packa upp och aktivera sedan en virtualenv:
$ cd django_heroku_deploy
$ virtualenv --no-site-packages myenv
$ source myenv/bin/activate
Skapa ett nytt arkiv på Github:
$ curl -u 'USER' https://api.github.com/user/repos -d '{"name":"REPO"}'
Var noga med att byta ut KEYWORDS med alla toppar med dina egna inställningar. Till exempel:
curl -u 'mjhea0' https://api.github.com/user/repos -d '{"name":"django-deploy-heroku-s3"}'
Lägg till en readme-fil, initiera det lokala Git-repoet och PUSH sedan den lokala kopian till 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
Var noga med att ändra URL:en till din repos URL som du skapade i föregående steg.
Skapa en ny MySQL-databas som heter 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
Uppdatera settings.py :
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_deploy',
'USER': 'root',
'PASSWORD': 'your_password',
}
}
Installera beroenden:
$ pip install -r requirements.txt
$ python manage.py syncdb
$ python manage.py runserver
Kör servern på http://localhost:8000/admin/ och se till att du kan logga in på admin. Lägg till några objekt i Whatever
objekt. Döda servern.
Konvertera från MySQL till Postgres
Obs! I denna hypotetiska situation, låt oss låtsas att du har arbetat med det här projektet ett tag med MySQL och nu vill du konvertera det till Postgres.
Installationsberoenden:
$ pip install psycopg2
$ pip install py-mysql2pgsql
Konfigurera en Postgres-databas:
$ psql -h localhost
psql (9.2.4)
Type "help" for help.
michaelherman=# CREATE DATABASE django_deploy;
CREATE DATABASE
michaelherman=# \q
Migrera data:
$ py-mysql2pgsql
Detta kommando skapar en fil som heter mysql2pgsql.yml , som innehåller följande information:
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
Uppdatera detta för din konfiguration. Det här exemplet täcker bara den grundläggande konverteringen. Du kan också inkludera eller exkludera vissa tabeller. Se hela exemplet här.
Överför data:
$ py-mysql2pgsql -v -f mysql2pgsql.yml
När data har överförts, se till att uppdatera dina settings.py fil:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"NAME": "your_database_name",
"USER": "foo",
"PASSWORD": "bar",
"HOST": "localhost",
"PORT": "5432",
}
}
Slutligen, synkronisera om databasen, kör testservern och lägg till ytterligare ett objekt i databasen för att säkerställa att konverteringen lyckades.
Lägg till en local_settings.py-fil
Genom att lägga till en local_settings.py fil kan du utöka settings.py fil med inställningar som är relevanta för din lokala miljö, medan den huvudsakliga settings.py fil används enbart för dina iscensättnings- och produktionsmiljöer.
Se till att du lägger till local_settings.py till din .gitignore fil för att hålla filen borta från dina arkiv. De som vill använda eller bidra till ditt projekt kan sedan klona repet och skapa sina egna local_settings.py fil som är specifik för sin egen lokala miljö.
Även om den här metoden att använda två inställningsfiler har varit konventionell i ett antal år, använder många Python-utvecklare nu ett annat mönster som kallas The One True Way. Vi kanske tittar på det här mönstret i en framtida handledning.
Uppdatera settings.py
Vi måste göra tre ändringar i våra nuvarande settings.py fil:
Ändra DEBUG
läge till false:
DEBUG = False
Lägg till följande kod längst ned i filen:
# 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
Uppdatera databasinställningarna:
# we only need the engine name, as heroku takes care of the rest
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
}
}
Skapa din local_settings.py fil:
$ touch local_settings.py
$ pip install dj_database_url
Lägg sedan till följande kod:
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",
}
}
Starta testservern för att se till att allt fortfarande fungerar. Lägg till några fler poster till databasen.
Heroku-inställningar
Lägg till en profil i huvudkatalogen:
$ touch Procfile
och lägg till följande kod i filen:
web: python manage.py runserver 0.0.0.0:$PORT --noreload
Installera Heroku verktygsbälte:
$ pip install django-toolbelt
Frys beroenden:
$ pip freeze > requirements.txt
Uppdatera wsgi.py fil:
from django.core.wsgi import get_wsgi_application
from dj_static import Cling
application = Cling(get_wsgi_application())
Testa dina Heroku-inställningar lokalt:
$ foreman start
Navigera till http://localhost:5000/.
Ser bra ut? Låt oss köra Amazon S3.
Amazon S3
Även om det är hypotetiskt möjligt att vara värd för statiska filer i din Heroku-repo, är det bäst att använda en tredje parts värd, särskilt om du har en kundvänd applikation. S3 är lätt att använda, och det kräver bara några få ändringar av dina settings.py fil.
Installationsberoenden:
$ pip install django-storages
$ pip install boto
Lägg till storages
och boto
till din INSTALLED_APPS
i “settings.py”
Lägg till följande kod längst ned i "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
AWS miljöberoende inställningar lagras som miljövariabler. Så vi behöver inte ställa in dessa från terminalen varje gång vi kör utvecklingsservern, vi kan ställa in dessa i vår virtualenv activate
manus. Ta AWS Bucket-namnet, Access Key ID och Secret Access Key från S3. Öppna myenv/bin/activate
och lägg till följande kod (se till att lägga till din specifika information som du precis hämtade från 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
Inaktivera och återaktivera din virtualenv, starta sedan den lokala servern för att se till att ändringarna trädde i kraft:
$ foreman start
Döda servern och uppdatera sedan requirements.txt fil:
$ pip freeze > requirements.txt
Push till Github och Heroku
Låt oss säkerhetskopiera våra filer till Github innan vi PUSHAR till Heroku:
$ git add .
$ git commit -m "update project for heroku and S3"
$ git push -u origin master
Skapa ett Heroku-projekt/repo:
$ heroku create <name>
Ge det vad du vill.
PUSH till Heroku:
$ git push heroku master
Skicka AWS miljövariabler till 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
Samla de statiska filerna och skicka till Amazon:
$ heroku run python manage.py collectstatic
Lägg till utvecklingsdatabas:
$ 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
Synkronisera nu DB:
$ heroku run python manage.py syncdb
Dataöverföring
Vi måste överföra data från den lokala databasen till produktionsdatabasen.
Installera Heroku PGBackups-tillägget:
$ heroku addons:add pgbackups
Dumpa din lokala databas:
$ pg_dump -h localhost -Fc library > db.dump
För att Heroku ska få tillgång till db dump måste du ladda upp den till Internet någonstans. Du kan använda en personlig webbplats, dropbox eller S3. Jag laddade helt enkelt upp den till S3-hinken.
Importera dumpningen till Heroku:
$ heroku pgbackups:restore DATABASE http://www.example.com/db.dump
Testa
Låt oss testa för att se till att allt fungerar.
Uppdatera först dina tillåtna värdar till din specifika domän i settings.py :
ALLOWED_HOSTS = ['[your-project-name].herokuapp.com']
Kolla in din app:
$ heroku open
Tyg
Fabric används för att automatisera distributionen av din applikation.
Installera:
$ pip install fabric
Skapa fabfilen:
$ touch fabfile.py
Lägg sedan till följande kod:
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')
Testa:
$ fab deploy
Har du frågor eller kommentarer? Gå med i diskussionen nedan.