Сегодня мы рассмотрим небольшой пример развёртывания Django приложения в AWS Elastic Beanstalk (с Postgres).
Убедитесь, что у вас установлен Python 2.7, pip, virtualenv (если нет, установите его командой «pip install virtualenv»), awsebcli (pip install awsebcli) и есть учётная запись AWS. Вы можете зарегистрировать бесплатную учётку, если ещё не сделали этого ранее.
1. Создание базы данных и пользователя
Установим postgres в Ubuntu:
sudo apt-get update
sudo apt-get install python-pip python-dev libpq-dev postgresql postgresql-contrib
После установки Postgres будет создан системный пользователь postgres, с помощью которого мы будем выполнять все действия с базой данных. Переключимся на него:
sudo su - postgres
Теперь мы работаем под postgres, далее мы войдём в PostgreSQL с помощью утилиты psql:
psql
CREATE DATABASE myproject;
CREATE USER myprojectuser WITH PASSWORD 'password';
Дадим пользователю myprojectuser полные права для работы с этой базой:
GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;
2. Настроим virtualenv и создадим проект Django
Создадим виртуальную среду и активируем её:
virtualenv ~/eb-venv
source ~/eb-venv/bin/activate
Установим в неё Django:
pip install django==1.11
Для проверки установленной django откроем консоль python и введём:
import django
django.VERSION
Если django установлен корректно, команда выведет версию установленного фреймворка (например, 1.11), иначе будет выведена ошибка.
Создадим проект Django:
~$ django-admin startproject ebdjango
Будет создан проект со следующей структурой:
~/ebdjango
|-- ebdjango
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| `-- wsgi.py
`-- manage.py
Теперь нужно проверить, что всё работает корректно. Для запуска Django-сервера локально, нужно добавить localhost или 127.0.0.1 в настройку ALLOWED_HOSTS в файле ~/ebdjango/ebdjango/settings.py. Отредактируем этот файл:
ALLOWED_HOSTS = ['localhost', '127.0.0.1', '.elasticbeanstalk.com']
(eb-venv) ~$ cd ebdjango
(eb-venv) ~/ebdjango$ python manage.py runserver
Готово. Откройте http://127.0.0.1:8000/ в браузере.
3. Настройка базы данных, миграции
(eb-venv) ~/ebdjango$ pip install django psycopg2
Откроем файл ~/ebdjango/ebdjango/settings.py, в нём будет секция DATABASES:
...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
...
Мы сменим движок базы данных с sqlite3 на postgresql_psycopg2 и добавим данные пользователя для подключения к ней и localhost как адрес сервера. Порт оставим пустым, чтобы было выбрано значение по-умолчанию.
...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'myproject',
'USER': 'myprojectuser',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '',
}
}
...
Запустим миграции базы данных для создания её структуры:
(eb-venv) ~/ebdjango$ python manage.py makemigrations
(eb-venv) ~/ebdjango$ python manage.py migrate
Далее создадим администратора:
(eb-venv) python manage.py createsuperuser
4. Конфигурационный файл миграции БД
Создадим конфигурационный файл ~/ebdjango/.ebextensions/db-migrate.config со следующим содержимым:
container_commands:
01_migrate:
command: "django-admin.py migrate"
leader_only: true
option_settings:
aws:elasticbeanstalk:application:environment:
DJANGO_SETTINGS_MODULE: ebdjango.settings
Этот файл запустит команду «django-admin.py migrate» во время развёртывания, прямо перед запуском приложения. И так как он выполнится до запуска приложения, вы должны явно прописать значение переменной DJANGO_SETTINGS_MODULE (обычно за это отвечает wsgi.py во время запуска). Указав leader_only: true, процесс выполнится только один раз, это важно при развёртывании нескольких экземпляров.
5. Настраиваем сайт для Elastic Beanstalk
Активируем виртуальную среду:
~/ebdjango$ source ~/eb-venv/bin/activate
Запускаем pip freeze и сохраняем вывод в файл requirements.txt:
(eb-venv) ~/ebdjango$ pip freeze > requirements.txt
Создадим папку .ebextensions
(eb-venv) ~/ebdjango$ mkdir .ebextensions
и в ней создадим файл django.config со следующим содержимым:
option_settings:
aws:elasticbeanstalk:container:python:
WSGIPath: ebdjango/wsgi.py
aws:elasticbeanstalk:container:python:staticfiles:
"/static": "static/"
container_commands:
01_collectstatic:
command: "python manage.py collectstatic --noinput"
leader_only: true
В переменной WSGIPath хранится путь до сценария WSGI, который Elastic Beanstalk использует для запуска приложения.
6. Создаём среду и развёртываем приложение Django
Создайте пользователя IAM здесь (если не сделали этого ранее). Нам понадобятся aws-access-id и aws-secret-key в дальнейшем.
Инициализируем репозиторий EB CLI командой eb init:
~/ebdjango$ eb init -p python2.7 django-tutorial
Запустим eb init ещё раз для настройки ключевой информации, необходимой для подключения к EC2 по SSH:
~/ebdjango$ eb init
Деплоим приложение:
~/ebdjango$ eb create django-env
После деплоя откроем наш сайт:
~/ebdjango$ eb open
Проверьте, что папка ~/ebdjango выглядит так:
~/ebdjango
|-- ebdjango
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| `-- wsgi.py
|-- manage.py
|-- requirements.txt
|-- .ebextensions
| |-- db-migrate.config
| `-- django.config
`-- .elasticbeanstalk
После того, как вы внесёте изменения в код приложения, задеплоить их можно так:
~/ebdjango$ eb deploy
Если у вас будет такая ошибка:
django.db.utils.OperationalError: could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 5432?
это просто говорит о том, что у нас не настроен postgresql на сервере, займёмся этим сейчас.
7. Настройка базы данных RDS Postgres
Откроем страницу конфигурации Elastic Beanstalk командой
~/ebdjango$ eb console
Идём в раздел Configuration, прокручиваем вниз и нажимаем «Create a new RDS instance». Вводим свои данные и нажимаем Apply. Через пару минут все будет готово.
Отредактируем параметр DATABASES в settings.py:
...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.environ['RDS_DB_NAME'],
'USER': os.environ['RDS_USERNAME'],
'PASSWORD': os.environ['RDS_PASSWORD'],
'HOST': os.environ['RDS_HOSTNAME'],
'PORT': os.environ['RDS_PORT'],
}
}
...
Добавим файл local_settings.py в одну папку с файлом settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'myproject',
'USER': 'myprojectuser',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '',
}
}
И добавим это в settings.py:
if os.environ.get('ENVIRONMENT') == "PROD":
print "Running on Production Environment settings"
else:
from local_settings import *
print "Running on Local Environment settings"
И, наконец, установим значение этого параметра:
~/ebdjango$ eb setenv ENVIRONMENT=PROD
Так мы отделим локальные настройки для разработки от настроек сервера.
Задеплоим изменения:
~/ebdjango$ eb deploy
Если у вас появятся какие-то ошибки, здесь описано как посмотреть логи в EC2.
Ссылки
- Демонстрационная версия приложения, созданная в этом посте.
- Исходный код приложения
По материалам «How to deploy a Django app on AWS (with Elastic Beanstalk)»
Разработчик: java, kotlin, c#, javascript, dart, 1C, python, php.
Пишите: @ighar. Buy me a coffee, please :).