# Часть девятая. Деплой проекта

**Цель:** Выгрузить сайт в интернет

**Задачи:**

* Указать три способа выгрузки сайта
* Осуществить первый способ
* Осуществить второй способ
* Осуществить третий способ

## Какие бывают способы деплоя?

Существует 3 способа выгрузить проект в интернет. Выгрузка проекта называется деплоем.

## Способ первый. WGET.

Этот способ самый дешёвый, но при это совершенно не правильный, хоть и простой. При использовании этого способа, сайт будет отображаться страница целиком, но никакие механизмы в нём работать не будут.

* Шаг 0 (для Windows). Скачать на компьютер wget. Это бесплатная утилита для скачивания сайтов целиком. В UNIX-образных системах она установлена.
* Шаг 1. Запускаем сервер.
* Шаг 2. Переходим в терминал/командную строку и пишем команду:

  ```
  wget -r -k -l 7 -p -E -nc <http://127.0.0.1:8080/>
  ```
* Шаг 3. Заходим в папку загрузки (по умолчанию – это папка пользователя) и находим папку с проектом.
* Шаг 4. Выгружаем папку целиком на публичный хостинг.

## Способ №2. Деплой при помощи PythonAnywhere

Плюсы данного способа – полноценный деплой и простота настройки. Главный минус – использование стороннего ПО.

Есть много компаний, предоставляющих сервера в интернете. Мы воспользуемся услугами одной из них, с довольно простым процессом публикации: PythonAnywhere (<https://www.pythonanywhere.com>). PythonAnywhere бесплатен для маленьких приложений с небольшим числом посетителей, и этого будет для нас более чем достаточно.

Другим внешним сервисом, которым мы воспользуемся, будет GitHub (<https://github.com>) — сервис хостинга кода. Существуют и другие похожие сервисы, но практически у каждого программиста есть GitHub аккаунт.

В итоге код будет в трёх местах. На локальном компьютере мы будем заниматься разработкой и тестированием. Когда результат полностью устроит, мы загрузим свою программу на GitHub. А сайт будет на PythonAnywhere, и мы сможем обновлять его, просто загружая новую версию кода с GitHub.

### Git

Git — это «система управления версиями», используемая множеством программистов. Эта программа отслеживает изменения, происходящие с файлами, чтобы впоследствии можно было восстановить состояние кода на нужный момент времени. Это немного похоже на функцию отслеживания изменений в Microsoft Word, но куда мощнее.

### Установка Git

#### Windows

Вы можете загрузить Git с официального сайта [git-scm.com](https://git-scm.com/). Можно нажимать "дальше, дальше, дальше" на всех этапах установки за исключением одного: на пятом шаге, который называется "Adjusting your PATH environment" (Настройка системной переменной Path), выберите "Use Git and optional Unix tools from the Windows Command Prompt" (Запуск Git и соответствующих Unix утилит через командную строку Windows, нижняя опция). Все остальные настройки можно оставить по умолчанию. Также неплохо будет выбрать опцию "Checkout Windows-style, commit Unix-style line endings".

После окончания установки не забудьте перезапустить командную строку или powershell.

#### OS X

Загрузи Git с официального сайта [git-scm.com](https://git-scm.com/) и просто следуй инструкциям по установке.

#### Debian и Ubuntu

```bash
command-line
$ sudo apt install git
```

#### Fedora

```bash
command-line
$ sudo dnf install git
```

#### openSUSE

```bash
command-line
$ sudo zypper install git
```

### Создаём Git-репозиторий

Git отслеживает изменения определенного набора файлов, который называется репозиторием. Давайте создадим такой для нашего проекта. Откройте консоль и запустите эти команды в папке saitMiigaika:

```bash
command-line
$ git init
Initialized empty Git repository in ~/saitMiigaika/.git/
$ git config --global user.name "Your Name"
$ git config --global user.email you@example.com
```

Инициализировать git-репозиторий придется только один раз за проект.

Git будет отслеживать изменения всех файлов и каталогов в заданной директории, однако некоторые из них мы предпочли бы игнорировать. Для этого нам нужно создать файл .gitignore в корневом каталоге репозитория. Откройте редактор и создай новый файл со следующим содержанием:

```
.gitignore
*.pyc
*~
__pycache__
myvenv
db.sqlite3
/static
.DS_Store
```

И сохраните его как .gitignore в корневом каталоге "saitMiigaika".

Используйте команду git status перед git add или в любой другой момент, когда вы не уверены, что изменения — хорошая идея. Это убережёт сайт от таких неприятных сюрпризов, как добавление неправильных файлов. Команда git status возвращает информацию обо всех ранее неотслеживаемых/изменённых/добавленных в git файлах, а также статус ветки и многое другое. Результат должен быть похож на:

```bash
command-line
$ git status
On branch master

No commits yet

Untracked files:
(use "git add <file>..." to include in what will be committed)

    .gitignore
    blog/
    manage.py
    mysite/

nothing added to commit but untracked files present (use "git add" to track)
```

И, наконец, мы сохраним наши изменения. Переключаемся на консоль и набираем:

```bash
command-line
$ git add --all .
$ git commit -m "My Django MIIGAiK app, first commit"
[...]
13 files changed, 200 insertions(+)
create mode 100644 .gitignore
[...]
create mode 100644 mysite/wsgi.py
```

**Загружаем код в репозиторий GitHub**

Зайдите на GitHub.com и создайте новую бесплатную учётную запись.

Затем создайте новый репозиторий и назови его "my-first-blog" (к примеру). Не выбирайте опцию "initialise with a README", не создавайте файл .gitignore (мы сделаем это локально сами) и оставьте лицензию None.

![](https://4078292694-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MNtNPjTNQxUDbrf3v0a%2F-MNy5ryJUMVmoennEgtw%2F-MNy5xtAxUqgdgFyPfxH%2F497baf905eecc53f8c5ff4dd27399f25.png?alt=media\&token=2598eac4-9207-4342-afb4-586aa420c154)

На следующем экране мы видим URL для клонирования репозитория. Выберите вариант "HTTPS" и скопируй ссылку:

![](https://4078292694-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MNtNPjTNQxUDbrf3v0a%2F-MNy5ryJUMVmoennEgtw%2F-MNy5xtCYXvy6VKUBJbC%2F314552b0164b856789e58421280d3936.png?alt=media\&token=bbbc0f95-bf4c-4b88-a31b-d7394bc78b3e)

Теперь нужно связать локальный репозиторий с репозиторием на GitHub.

Напечатайте у себя в консоли следующую команду (замените \ на имя, указанное при создании аккаунта на GitHub, но без угловых скобок):

```bash
command-line
$ git remote add origin https://github.com/<github-username>/my-first-blog.git
$ git push -u origin master
```

Введите свое имя пользователя и пароль от аккаунта GitHub; мы должны увидеть примерно следующее:

```bash
command-line
Username for 'https://github.com': Username
Password for 'https://hjwp\@github.com':
Counting objects: 6, done.
Writing objects: 100% (6/6), 200 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/hjwp/my-first-blog.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
```

Наш код теперь на GitHub. Зайдите на сайт и проверьте.

### Настройка блога на PythonAnywhere

#### Регистрация на PythonAnywhere

PythonAnywhere — это сервис по запуску кода на Python в облаке. Мы будем использовать его, чтобы разместить наш сайт «вживую» в интернете.

Создайте аккаунт уровня "Beginner" на PythonAnywhere. Он бесплатный.

{% embed url="<https://www.pythonanywhere.com>" %}

![](https://4078292694-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MNtNPjTNQxUDbrf3v0a%2F-MNy5ryJUMVmoennEgtw%2F-MNy5xt8yedh99V8zo3u%2F5ac760ca70496f7ac94f3e71361746c5.png?alt=media\&token=662e985d-9049-4eb0-8e03-2545787605b8)

#### Создание API токена для PythonAnywhere

Это нужно будет сделать только один раз. Когда вы зарегистрируетесь на PythonAnywhere, откроется панель управления (dashboard). На ней в правом верхнем углу будет ссылка на страницу «Account»:

![](https://4078292694-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MNtNPjTNQxUDbrf3v0a%2F-MNy5ryJUMVmoennEgtw%2F-MNy5xtEKhGKJP-zqk4y%2Fde5010b551425689a924cea98c26d5dc.png?alt=media\&token=4ed6c7c4-5782-45f3-bb09-d6b45548e96a)

Там выберите вкладку «API token» и нажмите кнопку, на которой написано «Create new API token» (создать новый API token).

![](https://4078292694-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MNtNPjTNQxUDbrf3v0a%2F-MNy5ryJUMVmoennEgtw%2F-MNy5xtDi8_51ANUJiC6%2Fd3c1fb98bc61eca9b91ff00386871fbc.png?alt=media\&token=bd828556-e043-4258-94bc-858416c366b2)

### Настройка сайта на PythonAnywhere

Вернитесь на главную страницу PythonAnywhere, кликнув логотип. Затем запустите Bash-консоль. Нажав на кнопку bash мы запускаем командную строку, которая находится на серверах PythonAnywhere. Эта командная строка аналогична тому, что есть на компьютере.

![](https://4078292694-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MNtNPjTNQxUDbrf3v0a%2F-MNy5ryJUMVmoennEgtw%2F-MNy5xtBZ6HO68EcFIGt%2F649e4fb86dc9441945f120a3884f5524.png?alt=media\&token=d4c158a3-1447-4551-a3ef-1267741b7c2c)

Чтобы опубликовать сайт на PythonAnywhere, нужно загрузить на PythonAnywhere код с Github и затем настроить PythonAnywhere так, чтобы он распознал код и запустил веб-приложение. Существуют способы сделать это «вручную», но для PythonAnywhere есть программа-помощник, которая сделает это за нас. Давайте её установим.

```bash
PythonAnywhere command-line
$ pip3.6 install --user pythonanywhere
```

Когда мы это запустим, в консоли будет печататься лог установки. Он начнётся с чего-то вроде Collecting pythonanywhere, а последней будет строчка `Successfully installed (...) pythonanywhere- (...)`.

Теперь запустим эту вспомогательную утилиту, которую только что установили. Она настроит приложение, скачав его код с GitHub. Напечатайте следующее в консоли PythonAnywhere:

```bash
PythonAnywhere command-line
$ pa_autoconfigure_django.py https://github.com/<github-username>/my-first-blog.git
```

Утилита будет печатать в консоль, что она делает:

* Скачивает код с GitHub
* Создаёт виртуальное окружение на PythonAnywhere, такое же, как на компьютере
* Обновляет файл настроек с настройками деплоя
* Создаёт базу данных на PythonAnywhere, используя команду manage.py migrate
* Разбирается со статическими файлами
* Настраивает PythonAnywhere так, чтобы приложение было доступно в интернете

Все эти шаги автоматизированы на PythonAnywhere, но они совершенно такие же, какие надо было бы совершить с любым другим хостинговым сервисом.

Главное, на что нужно обратить внимание сейчас, — это то, что база данных на PythonAnywhere никак не связана с базой данных на компьютере. Поэтому там будут разные посты и разные аккаунты администраторов. Как следствие, для базы на PythonAnywhere необходимо создать аккаунт администратора так же, как мы это дели локально с помощью команды createsuperuser. На PythonAnywhere заранее активировано виртуальное окружение, так что всё, что нужно сделать — это запустить в консоли PythonAnhywhere команду:

```bash
PythonAnywhere command-line
(ola.pythonanywhere.com) $ python manage.py createsuperuser
```

Введите параметры для своего пользователя-админа. Лучше всего использовать те же самые данные, что и на локальном компьютере, чтобы избежать путаницы.

Сейчас, если хотите, посмотрите на файлы на PythonAnywhere с помощью команды ls:

```bash
PythonAnywhere command-line
(ola.pythonanywhere.com) $ ls
blog db.sqlite3 manage.py mysite requirements.txt static
(ola.pythonanywhere.com) $ ls blog/
__init__.py __pycache__ admin.py apps.py migrations models.py tests.py views.py
```

## Вариант 3. Без автоматизации PythonAnywhere (не рекомендуется новичку)

Самый сложный, но при этом самый правильный метод настройки, так как нам не потребуется использовать стороннее ПО для деплоя, а это уменьшает число уязвимостей.

Необходимо купить выделенный VDS или VPS сервер. VDS выделяет место на сервере физически, VPS – программным методом.

Предположим, у Вас куплена свежая машина, мы первый раз к ней подключаемся. Используем мы Ubuntu.

Далее буду вводить команды списком, чтобы не запутаться в шагах.

* [ ] Если у вас уже прописан ключ к вашей машине, но он не совпадает, очищаете его

```bash
rm .ssh/known_hosts
```

* [ ] Подключаетесь и вводите пароль от сервера.

```bash
ssh root\@5.45.120.175
```

* [ ] Обновляете пароль рута, если он вас не устраивает

```bash
passwd root
```

* [ ] Обновляем списки репозиториев.

```bash
apt-get update
```

* [ ] Апгредим.

```bash
apt-get upgrade
```

* [ ] Если присутствуют проблемы локали, исправляем их сразу.

```bash
perl -v
```

* [ ] Смотрим, если ругается и есть предупреждения генерируем локаль.

```bash
locale-gen en_US en_US.UTF-8 ru_RU.UTF-8
```

* [ ] Затем реконфигурируем локаль машины.

```bash
dpkg-reconfigure locales
```

* [ ] Вновь проверяем на наличие ошибок

```bash
perl -v
```

* [ ] Ура их нет! Двигаемся дальше. Устанавливаем Nginx.

```bash
apt-get install nginx
```

* [ ] После установки запускаем nginx.

```bash
service nginx start
```

* [ ] Смотрим статус:

```bash
service nginx status
```

* [ ] Если все ок, и он запущен можете открыть страничку вашего сайта и вы увидите

  стартовую страницу nginx. Если же сервер не запустился, проверте, не запущен ли

  у вас apache

```bash
service apache2 status
```

* [ ] Если он запущен стопайте его. Его необходимо полностью удалить.

```bash
service apache2 stop
```

* [ ] Деинсталируем апач и все его конфиги такой вот не хитрой командой:

```bash
apt-get purge apache2 apache2-utils apache2.2-bin apache2-common
```

* [ ] Если какие то пакеты, которые собираемся удалить отсутствуют, просто уберите

  их из команды. Далее:

```bash
apt-get autoremove
```

* [ ] Наконец, надо проверить наличие конфигурационных файлов или мануалов,

  связанных с Apache2, но до сих пор не удаленных.

```bash
whereis apache2
```

* [ ] Удаляете все эти директории вручную. Например, вот так:

```bash
rm -rf /etc/apache2
```

* [ ] Если все удалено, аллилуя. Запускаем nginx. И смотрим статус:

```bash
service nginx start
service nginx status
```

* [ ] Если все ок, заходите на вашу страничку и вы увидете стартовую страницу

  nginx. Идем дальше. Cоздайте пользователя для старта django-приложения. Создайте

  из-под него виртуальное окружение.

```bash
apt-get install python3-dev python3-setuptools
easy_install-3.4 virtualenv
adduser django
login django
cd /home/django
virtualenv venv
```

* [ ] Теперь, переносим проект в эту папку.Устанавливаем git, nano если они не

  установлены.

```bash
apt-get install git nano
```

* [ ] Создаем ключ ssh. Все поля оставляем пустыми.

```bash
ssh-keygen -t rsa -C "your_mail\@mail.com"
```

* [ ] Переходим в директорию ключа, открываем необходимый нам публичный ключ.

  Советую с помощью утилиты sshfs подключиться к вашей машине через gui интерфейс.

  Вам будет необходимо указать адрес машины и папку, в которую поместите файлы

  машины. Например вот так.

```bash
sshfs root@5.45.120.175:/ /home/user/Develop/sites/my_site/
```

* [ ] Затем копируете ключ.

```bash
/root/.ssh/id_rsa.pub
```

* [ ] Копируем его в настройки пользователя git репозитория
* [ ] После того, как вы это сделаете, вы сможете спокойно клонировать по ssh репозиторий. Заходите под рутом.

```bash
su - root
cd /home/django/
git clone git@github.com:user/my_site.git
```

* [ ] Симлинк `/etc/nginx/sites-enabled/default` можно удалить
* [ ] Логинимся под юзером django.

```bash
login django
```

* [ ] Активируем виртуальное окружение.

```bash
source venv/bin/activate
```

* [ ] Устанавливаем Django в наше виртуальное окружене:

```bash
pip install Django
```

* [ ] Переходим в корневую папку проекта.

```bash
cd my_site
```

* [ ] Один из хороших способов установить uWSGI:

```bash
pip install uwsgi
```

* [ ] Проверка. Создаем файл test.py:

```bash
nano test.py
```

* [ ] С таким содержимым:(Если не создается, создайте от рута)

```bash
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"]
```

* [ ] Запускаем uWSGI:

```bash
uwsgi --http :8000 --wsgi-file test.py
```

* [ ] Если все работает, нажимаем `ctrl-c`, завершая процесс и продолжаем дальше.
* [ ] Теперь конфигурируем наш сайт. Устанавливаем postgresql. Из под рута.

```bash
apt-get install libpq-dev postgresql postgresql-contrib
su - postgres
createdb my_site
createuser -P django
psql
postgres=# GRANT ALL PRIVILEGES ON DATABASE my_site TO django;
su - root
login django
source /home/django/venv/bin/activate
pip install psycopg2
```

* [ ] Если необходимо перенести БД со старой на новую делается это так:
* [ ] Шаг 1. Выполняется со старыми настройками DATABASES в settings.py python manage.py dumpdata > datadump.json
* [ ] Шаг 2. Выполняется с новыми настройками DATABASES в settings.py python manage.py loaddata datadump.json
* [ ] После этого устанавливаем все библиотеки что есть в `requirements.txt`. Для этого заходим в папку my\_site проектом и вводим следующую команду. Разумеется с помощью виртуального окружения.

```bash
pip install -r requirements.txt
```

* [ ] Если не установилась какая-нибудь библиотека X устанавливайте более позднюю

  версию:

```bash
pip install X==2.9.0
```

* [ ] В файле …/my\_site/settings.py обязательно нужно указать настройки базы

  данных:

```python
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'my_site',
        'USER': 'django',
        'PASSWORD': '1234567890',
        'HOST': 'localhost',
        'PORT': '',
    }
}
```

* [ ] В файле settings.py должен быть такой путь:

```python
MEDIA_ROOT = "/home/django/my_site/media"
```

* [ ] Делаем миграцию, если это необходимо:

```bash
python manage.py migrate
```

* [ ] Создаем супер пользователя.

```bash
python manage.py createsuperuser
```

* [ ] Запускаем сервер

```bash
python manage.py runserver 0.0.0.0:8080
```

* [ ] Если ошибок не возникло, заходим и настраиваем сайт через панель администратора (если у вас новая свежая база данных без данных).
* [ ] После того, как вы сконфигурировали проект идем дальше. Собираем всю статику (Скорее всего это сработает только из под рута):

```bash
python manage.py collectstatic
```

* [ ] Теперь, вы можете запустить my\_site через uwsgi, и если это не сработало, значит вы где то совершили ошибку. Вполне вероятно, о ней сообщат логи uwsgi.

```bash
uwsgi --http :8000 --module my_site.wsgi
```

* [ ] Теперь нам необходимо сконфигурировать nginx. Для начала, создайте файл в корне проекта `my_site` с названием `uwsgi_params`, с таким содержанием:

```bash
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
```

* [ ] Вообще, лучше поместите этот файл в корень проекта, в папку с названием `deployment`, чтобы файлы проекта различались с файлами деплоя.
* [ ] Теперь в той же папке создайте файл `my_site_nginx.conf`
* [ ] Наполните его таким содержимым:

```
# the upstream component nginx needs to connect to
upstream django {
    server unix:///home/django/my_site/uwsgi_nginx.sock; # for a file socket
    # server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}

# configuration of the server
server {
    # the port your site will be served on
    listen 8000;
    # the domain name it will serve for
    server_name my_site.ru; # substitute your machine's IP address or FQDN
    charset utf-8;

    # max upload size
    client_max_body_size 75M; # adjust to taste

    # Django media
    location /media {
        alias /home/django/my_site/media; # your Django project's media files - amend as required
    }

    location /static {
    alias /home/django/my_site/static; # your Django project's static files - amend as required
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass django;
        include /home/django/my_site/deployment/uwsgi_params; # the uwsgi_params file you installed
    }
}
```

* [ ] В папке /etc/nginx/sites-enabled создаем ссылку на файл `mysite_nginx.conf`, чтобы nginx увидел его.

```bash
sudo ln -s /home/django/rss_news/deployment/rss_news_nginx.conf /etc/nginx/sites-enabled
```

* [ ] Перезапускаем nginx:

```bash
/etc/init.d/nginx restart
```

* [ ] Помещаем файл с именем, например, media.png в папку /home/django/my\_site/media.
* [ ] В браузере переходим по адресу yourserver.com:8000/media/media.png и, если видим наш файл, значит мы все сделали правильно.
* [ ] Пробуем запустить через сокет:

```bash
uwsgi --socket uwsgi_nginx.sock --wsgi-file test.py —-chmod-socket=666
```

* [ ] nginx + uWSGI + Django. Запускаем: В браузере переходим на yourserver.com:8000/ и видим стартовую страницу Django.

```bash
uwsgi --socket uwsgi_nginx.sock --module my_site.wsgi --chmod-socket=666
```

* [ ] Мы собрали всю цепочку, но настройка еще не закончена, идем дальше.
* [ ] Очень удобно все опции, с которыми мы запускаем uWSGI, указать в ini файле, а при запуске передавать только путь к этому файлу. Создаем файл my\_site\_uwsgi.ini в нашей папке deployment. Указываем в нем следующее содержимое:

```
#mysite_uwsgi.ini
[uwsgi]

# Настройки, связанные с Django
# Корневая папка проекта (полный путь)
chdir = /home/django/my_site
# Django wsgi файл
module = my_site.wsgi
# полный путь к виртуальному окружению
home = /home/django/venv
# общие настройки
# master
master = true
# максимальное количество процессов
processes = 10
# полный путь к файлу сокета
socket = /home/django/my_site/uwsgi_nginx.sock
# права доступа к файлу сокета
chmod-socket = 666
# очищать окружение от служебных файлов uwsgi по завершению
vacuum = true
env = DEBUG_MODE=False
daemonize=/var/log/uwsgi/my_site.log
```

* [ ] Запускаем этот файл:

```bash
uwsgi --ini my_site_uwsgi.ini
```

* [ ] Проверяем. Все работает? Дальше. До сих пор uWSGI был установлен в виртуальном окружении. Чтобы была возможность автоматически запускать uWSGI при старте операционной системы, мы установим его глобально. Деактивируем виртуальное окружение:

```bash
deactivate
```

* [ ] Устанавливаем pip и pip3 глобально.

```bash
apt-get install python-pip python3-pip
```

* [ ] Затем, устанавливаем uwsgi глобально.

```bash
pip3 install uwsgi
```

* [ ] Проверяем запуск:

```bash
uwsgi --ini my_site_uwsgi.ini
```

* [ ] Если сервер обслуживает несколько проектов, каждый из которых использует uWSGI, то нужно использовать режим Emperor. В этом режиме uWSGI просматривает папку с конфигурационными файлами и для каждого файла запускает отдельный процесс (вассал).

  Если один из конфигурационных файлов будет изменен, uWSGI перезапустит соответствующего вассала.

  Создаем папку для конфигурационных файлов:

```bash
sudo mkdir /etc/uwsgi

sudo mkdir /etc/uwsgi/vassals
```

* [ ] Создаем в ней ссылку на `my_site_uwsgi.ini`:

```bash
sudo ln -s /home/django/my_site/deployment/my_site_uwsgi.ini /etc/uwsgi/vassals/
```

* [ ] Запускаем uWSGI в режиме Emperor, потом отключаем если все работает (Возможно вам придется перезапустить вашу БД такой командой `sudo service postgresql restart`):

```bash
uwsgi --emperor "/home/django/my_site/deployment/my_site_uwsgi.ini"
```

* [ ] Устанавливаем супервизор

```bash
apt-get install supervisor
```

* [ ] Создаем файл конфигурации в папке etc/supervisor/conf.d/my\_site.conf:

```bash
echo_supervisord_conf > /etc/supervisord.conf
```

* [ ] В Этом файле указываем следующий текст:

```
[program:my_site]
command=uwsgi --emperor "/home/django/my_site/deployment/my_site_uwsgi.ini"
stdout_logfile=/home/django/my_site/deployment/uwsgi.log
stderr_logfile=/home/django/my_site/deployment/uwsgi_err.log
autostart=true
autorestart=true
```

* [ ] Индексируем этот файл: (Если появляются какие то ошибки, перезапускаем supervisor (`service supervisor restart)`) Так же, смотрим логи.

```bash
supervisorctl reread
supervisorctl update
```

* [ ] Все должно работать. Управлять supervisor можно как сервисом:

```bash
service supervisor start|stop|status ...
```

* [ ] Если происходят какие то изменения в коде, выполняем эту команду в папке deployment:

```bash
service supervisor stop
touch my_site_uwsgi.ini
service supervisor start
```

* [ ] Команда supervisorctl покажет запущенные приложения императором.
* [ ] Если необходимо запустить проект в режиме дебага, меняем значение `DEBUG_MODE=False` на `DEBUG_MODE=True` в файле конфигурации uwsgi.
* [ ] Готово!
