I denne tutorial tager vi et simpelt lokalt Django-projekt, understøttet af en MySQL-database, og konverterer det til at køre på Heroku. Amazon S3 vil blive brugt til at være vært for vores statiske filer, mens Fabric vil automatisere implementeringsprocessen.
Projektet er et simpelt meddelelsessystem. Det kunne være en todo-app eller en blog eller endda en Twitter-klon. For at simulere et virkeligt scenarie vil projektet først blive oprettet med en MySQL-backend og derefter konverteret til Postgres til implementering på Heroku. Jeg har personligt haft fem eller seks projekter, hvor jeg har været nødt til at gøre præcis denne ting:konvertere et lokalt projekt, understøttet af MySQL, til en live-app på Heroku.
Opsætning
Forudsætninger
- Læs den officielle Django Quick Start-guide hos Heroku. Bare læs det. Dette vil hjælpe dig med at få en fornemmelse af, hvad vi vil opnå i denne vejledning. Vi vil bruge det officielle selvstudie som en guide til vores egen, mere avancerede implementeringsproces.
- Opret en AWS-konto, og opret en aktiv S3-bøtte.
- Installer MySQL.
Lad os begynde
Start med at downloade testprojektet her, unzip, og aktiver derefter en virtualenv:
$ cd django_heroku_deploy
$ virtualenv --no-site-packages myenv
$ source myenv/bin/activate
Opret et nyt lager på Github:
$ curl -u 'USER' https://api.github.com/user/repos -d '{"name":"REPO"}'
Sørg for at udskifte alle hætter NØGLEORD med dine egne indstillinger. For eksempel:curl -u 'mjhea0' https://api.github.com/user/repos -d '{"name":"django-deploy-heroku-s3"}'
Tilføj en readme-fil, initialiser den lokale Git-repo, og PUSH derefter den lokale kopi til 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
Sørg for at ændre URL'en til din repos URL, som du oprettede i det forrige trin.
Opsæt en ny MySQL-database kaldet 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
Opdater settings.py :
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_deploy',
'USER': 'root',
'PASSWORD': 'your_password',
}
}
Installer afhængighederne:
$ pip install -r requirements.txt
$ python manage.py syncdb
$ python manage.py runserver
Kør serveren på http://localhost:8000/admin/, og sørg for at du kan logge ind på admin. Tilføj et par elementer til Whatever
objekt. Dræb serveren.
Konverter fra MySQL til Postgres
Bemærk: I denne hypotetiske situation, lad os foregive, at du har arbejdet på dette projekt i et stykke tid ved hjælp af MySQL, og nu vil du konvertere det til Postgres.
Installationsafhængigheder:
$ pip install psycopg2
$ pip install py-mysql2pgsql
Opsæt en Postgres-database:
$ psql -h localhost
psql (9.2.4)
Type "help" for help.
michaelherman=# CREATE DATABASE django_deploy;
CREATE DATABASE
michaelherman=# \q
Migrer data:
$ py-mysql2pgsql
Denne kommando opretter en fil kaldet mysql2pgsql.yml , der indeholder følgende oplysninger:
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
Opdater dette til din konfiguration. Dette eksempel dækker kun den grundlæggende konvertering. Du kan også inkludere eller ekskludere visse tabeller. Se det fulde eksempel her.
Overfør dataene:
$ py-mysql2pgsql -v -f mysql2pgsql.yml
Når dataene er overført, skal du sørge for at opdatere dine settings.py fil:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"NAME": "your_database_name",
"USER": "foo",
"PASSWORD": "bar",
"HOST": "localhost",
"PORT": "5432",
}
}
Til sidst skal du synkronisere databasen igen, køre testserveren og tilføje endnu et element til databasen for at sikre, at konverteringen lykkedes.
Tilføj en local_settings.py-fil
Ved at tilføje en local_settings.py fil, kan du udvide settings.py fil med indstillinger, der er relevante for dit lokale miljø, mens de vigtigste settings.py fil bruges udelukkende til dine iscenesættelses- og produktionsmiljøer.
Sørg for at tilføje local_settings.py til din .gitignore fil for at holde filen ude af dine arkiver. De, der ønsker at bruge eller bidrage til dit projekt, kan derefter klone repoen og oprette deres egen local_settings.py fil, der er specifik for deres eget lokale miljø.
Selvom denne metode til at bruge to indstillingsfiler har været tradition i en årrække, bruger mange Python-udviklere nu et andet mønster kaldet The One True Way. Vi ser muligvis på dette mønster i et fremtidigt selvstudie.
Opdater settings.py
Vi skal foretage tre ændringer af vores nuværende settings.py fil:
Skift DEBUG
tilstand til falsk:
DEBUG = False
Tilføj følgende kode til bunden af 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
Opdater databaseindstillingerne:
# we only need the engine name, as heroku takes care of the rest
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
}
}
Opret din local_settings.py fil:
$ touch local_settings.py
$ pip install dj_database_url
Tilføj derefter følgende kode:
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",
}
}
Tænd testserveren for at sikre, at alt stadig fungerer. Tilføj nogle flere poster til databasen.
Heroku-opsætning
Tilføj en profil til hovedbiblioteket:
$ touch Procfile
og tilføj følgende kode til filen:
web: python manage.py runserver 0.0.0.0:$PORT --noreload
Installer Heroku-værktøjsbæltet:
$ pip install django-toolbelt
Frys afhængighederne:
$ pip freeze > requirements.txt
Opdater wsgi.py fil:
from django.core.wsgi import get_wsgi_application
from dj_static import Cling
application = Cling(get_wsgi_application())
Test dine Heroku-indstillinger lokalt:
$ foreman start
Naviger til http://localhost:5000/.
Ser godt ud? Lad os få Amazon S3 til at køre.
Amazon S3
Selvom det hypotetisk er muligt at hoste statiske filer i din Heroku-repo, er det bedst at bruge en tredjepartsvært, især hvis du har en kundevendt applikation. S3 er nem at bruge, og det kræver kun få ændringer af dine settings.py fil.
Installationsafhængigheder:
$ pip install django-storages
$ pip install boto
Tilføj storages
og boto
til din INSTALLED_APPS
i "settings.py"
Tilføj følgende kode til bunden af "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øafhængige indstillinger gemmes som miljøvariabler. Så vi behøver ikke at indstille disse fra terminalen hver gang vi kører udviklingsserveren, vi kan indstille dem i vores virtualenv activate
manuskript. Få fat i AWS Bucket-navnet, adgangsnøgle-id'et og hemmelig adgangsnøgle fra S3. Åbn myenv/bin/activate
og tilføj følgende kode (sørg for at tilføje dine specifikke oplysninger, du lige har hentet fra 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
Deaktiver og genaktiver din virtualenv, start derefter den lokale server for at sikre dig, at ændringerne fik virkning:
$ foreman start
Dræb serveren, og opdater derefter requirements.txt fil:
$ pip freeze > requirements.txt
Skub til Github og Heroku
Lad os sikkerhedskopiere vores filer til Github, før vi PUSHER til Heroku:
$ git add .
$ git commit -m "update project for heroku and S3"
$ git push -u origin master
Opret et Heroku-projekt/Repo:
$ heroku create <name>
Navngiv det, hvad du vil.
PUSH til Heroku:
$ git push heroku master
Send AWS-miljøvariablerne til 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
Saml de statiske filer og send til Amazon:
$ heroku run python manage.py collectstatic
Tilføj udviklingsdatabase:
$ 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
Synkroniser nu DB:
$ heroku run python manage.py syncdb
Dataoverførsel
Vi skal overføre data fra den lokale database til produktionsdatabasen.
Installer Heroku PGBackups-tilføjelsen:
$ heroku addons:add pgbackups
Dump din lokale database:
$ pg_dump -h localhost -Fc library > db.dump
For at Heroku kan få adgang til db dump, skal du uploade det til internettet et eller andet sted. Du kan bruge en personlig hjemmeside, dropbox eller S3. Jeg har simpelthen uploadet det til S3-bøtten.
Importer dumpet til Heroku:
$ heroku pgbackups:restore DATABASE http://www.example.com/db.dump
Test
Lad os teste for at sikre, at alt fungerer.
Først skal du opdatere dine tilladte værter til dit specifikke domæne i settings.py :
ALLOWED_HOSTS = ['[your-project-name].herokuapp.com']
Tjek din app:
$ heroku open
Stof
Fabric bruges til at automatisere implementeringen af din applikation.
Installer:
$ pip install fabric
Opret fab-filen:
$ touch fabfile.py
Tilføj derefter følgende kode:
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
Har du spørgsmål eller kommentarer? Deltag i diskussionen nedenfor.