Развёртывание приложения Django в AWS Elastic Beanstalk

Развёртывание приложения Django в AWS Elastic Beanstalk
Сегодня мы рассмотрим небольшой пример развёртывания 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. Через пару минут все будет готово.

Развёртывание приложения Django в AWS Elastic Beanstalk
Отредактируем параметр 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)»

Leave a Comment