В този урок ще вземем прост локален проект на Django, подкрепен от MySQL база данни, и ще го преобразуваме за изпълнение на Heroku. Amazon S3 ще се използва за хостване на нашите статични файлове, докато Fabric ще автоматизира процеса на внедряване.
Проектът е проста система за съобщения. Това може да бъде приложение за задачи или блог или дори клонинг на Twitter. За да се симулира реален сценарий, проектът първо ще бъде създаден с MySQL бекенд, след което ще бъде преобразуван в Postgres за внедряване на Heroku. Аз лично имах пет или шест проекта, в които трябваше да направя точно това нещо:да конвертирам локален проект, подкрепен с MySQL, в приложение на живо на Heroku.
Настройка
Предварителни условия
- Прочетете официалното ръководство за бърз старт на Django в Heroku. Просто го прочетете. Това ще ви помогне да усетите какво ще постигнем в този урок. Ще използваме официалния урок като ръководство за нашия собствен, по-усъвършенстван процес на внедряване.
- Създайте акаунт в AWS и настройте активен сегмент S3.
- Инсталирайте MySQL.
Да започнем
Започнете, като изтеглите тестовия проект тук, разархивирайте и след това активирайте virtualenv:
$ cd django_heroku_deploy
$ virtualenv --no-site-packages myenv
$ source myenv/bin/activate
Създайте ново хранилище на Github:
$ curl -u 'USER' https://api.github.com/user/repos -d '{"name":"REPO"}'
Уверете се, че сте заменили всички главни КЛЮЧОВИ ДУМИ с вашите собствени настройки. Например:
curl -u 'mjhea0' https://api.github.com/user/repos -d '{"name":"django-deploy-heroku-s3"}'
Добавете файл readme, инициализирайте локалното репозиторие на Git, след което PUSH локалното копие към 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
Не забравяйте да промените URL адреса на URL адреса на вашето репо, който сте създали в предишната стъпка.
Настройте нова MySQL база данни, наречена 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
Актуализирайте settings.py :
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_deploy',
'USER': 'root',
'PASSWORD': 'your_password',
}
}
Инсталирайте зависимостите:
$ pip install -r requirements.txt
$ python manage.py syncdb
$ python manage.py runserver
Стартирайте сървъра на адрес http://localhost:8000/admin/ и се уверете, че можете да влезете в администратора. Добавете няколко елемента към Whatever
обект. Убийте сървъра.
Конвертиране от MySQL в Postgres
Забележка: В тази хипотетична ситуация, нека се преструваме, че сте работили по този проект известно време, използвайки MySQL и сега искате да го конвертирате в Postgres.
Инсталиране на зависимости:
$ pip install psycopg2
$ pip install py-mysql2pgsql
Настройте база данни на Postgres:
$ psql -h localhost
psql (9.2.4)
Type "help" for help.
michaelherman=# CREATE DATABASE django_deploy;
CREATE DATABASE
michaelherman=# \q
Мигриране на данни:
$ py-mysql2pgsql
Тази команда създава файл, наречен mysql2pgsql.yml , съдържаща следната информация:
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
Актуализирайте това за вашата конфигурация. Този пример обхваща само основното преобразуване. Можете също да включите или изключите определени таблици. Вижте пълния пример тук.
Прехвърлете данните:
$ py-mysql2pgsql -v -f mysql2pgsql.yml
След като данните бъдат прехвърлени, не забравяйте да актуализирате своя settings.py файл:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"NAME": "your_database_name",
"USER": "foo",
"PASSWORD": "bar",
"HOST": "localhost",
"PORT": "5432",
}
}
Накрая, повторно синхронизирайте базата данни, стартирайте тестовия сървър и добавете друг елемент към базата данни, за да сте сигурни, че преобразуването е успешно.
Добавете файл local_settings.py
Като добавите local_settings.py файл, можете да разширите settings.py файл с настройки, подходящи за вашата локална среда, докато основният settings.py файлът се използва единствено за вашите сценични и производствени среди.
Уверете се, че сте добавили local_settings.py към вашия .gitignore файл, за да запазите файла извън вашите хранилища. Тези, които искат да използват или да допринесат за вашия проект, могат след това да клонират репо и да създадат свой собствен local_settings.py файл, специфичен за тяхната собствена локална среда.
Въпреки че този метод за използване на два файла с настройки е конвенционален от няколко години, много разработчици на Python сега използват друг модел, наречен The One True Way. Може да разгледаме този модел в бъдещ урок.
Актуализиране на settings.py
Трябва да направим три промени в текущите ни settings.py файл:
Променете DEBUG
режим на false:
DEBUG = False
Добавете следния код в долната част на файла:
# 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
Актуализирайте настройките на базата данни:
# we only need the engine name, as heroku takes care of the rest
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
}
}
Създайте своя local_settings.py файл:
$ touch local_settings.py
$ pip install dj_database_url
След това добавете следния код:
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",
}
}
Стартирайте тестовия сървър, за да се уверите, че всичко все още работи. Добавете още няколко записа към базата данни.
Настройка на Heroku
Добавете Procfile към главната директория:
$ touch Procfile
и добавете следния код към файла:
web: python manage.py runserver 0.0.0.0:$PORT --noreload
Инсталирайте лентата с инструменти Heroku:
$ pip install django-toolbelt
Замразяване на зависимостите:
$ pip freeze > requirements.txt
Актуализирайте wsgi.py файл:
from django.core.wsgi import get_wsgi_application
from dj_static import Cling
application = Cling(get_wsgi_application())
Тествайте локално настройките на Heroku:
$ foreman start
Отидете до http://localhost:5000/.
Изглежда добре? Нека стартираме Amazon S3.
Amazon S3
Въпреки че хипотетично е възможно да хоствате статични файлове във вашето репо Heroku, най-добре е да използвате хост на трета страна, особено ако имате приложение, насочено към клиента. S3 е лесен за използване и изисква само няколко промени във вашия settings.py файл.
Инсталиране на зависимости:
$ pip install django-storages
$ pip install boto
Добавете storages
и boto
към вашите INSTALLED_APPS
в “settings.py”
Добавете следния код в долната част на “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 се съхраняват като променливи на околната среда. Така че не е нужно да ги задаваме от терминала всеки път, когато стартираме сървъра за разработка, можем да ги зададем в нашия virtualenv activate
скрипт. Вземете името на AWS Bucket, ID на ключа за достъп и секретния ключ за достъп от S3. Отворете myenv/bin/activate
и добавете следния код (не забравяйте да добавите вашата конкретна информация, която току-що изтеглите от 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
Деактивирайте и активирайте отново вашия virtualenv, след което стартирайте локалния сървър, за да се уверите, че промените са се отразили:
$ foreman start
Убийте сървъра, след което актуализирайте requirements.txt файл:
$ pip freeze > requirements.txt
Натиснете към Github и Heroku
Нека архивираме нашите файлове в Github, преди да PUSH на Heroku:
$ git add .
$ git commit -m "update project for heroku and S3"
$ git push -u origin master
Създайте проект/репо Heroku:
$ heroku create <name>
Назовете го както искате.
НАТИСНЕТЕ към Heroku:
$ git push heroku master
Изпратете променливите на средата на AWS до 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
Съберете статичните файлове и ги изпратете до Amazon:
$ heroku run python manage.py collectstatic
Добавете база данни за разработка:
$ 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
Сега синхронизирайте DB:
$ heroku run python manage.py syncdb
Прехвърляне на данни
Трябва да прехвърлим данните от локалната база данни в производствената база данни.
Инсталирайте добавката Heroku PGBackups:
$ heroku addons:add pgbackups
Изхвърлете вашата локална база данни:
$ pg_dump -h localhost -Fc library > db.dump
За да може Heroku да има достъп до db dump, трябва да го качите някъде в Интернет. Можете да използвате личен уебсайт, дропбокс или S3. Просто го качих в кофата на S3.
Импортирайте дъмпа в Heroku:
$ heroku pgbackups:restore DATABASE http://www.example.com/db.dump
Тест
Нека тестваме, за да се уверим, че всичко работи.
Първо, актуализирайте разрешените си хостове до вашия конкретен домейн в settings.py :
ALLOWED_HOSTS = ['[your-project-name].herokuapp.com']
Разгледайте приложението си:
$ heroku open
Тъкан
Fabric се използва за автоматизиране на внедряването на вашето приложение.
Инсталиране:
$ pip install fabric
Създайте fabfile:
$ touch fabfile.py
След това добавете следния код:
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')
Тест:
$ fab deploy
Имате въпроси или коментари? Присъединете се към дискусията по-долу.