Мега-Учебник Flask, Часть XVII: Развертывание под Linux
(издание 2018)
Miguel Grinberg
Туда Сюда
Это семнадцатая часть серии Мега-учебников Flask, в которой я собираюсь развернуть микроблог на сервере Linux.
Под спойлером приведен список всех статей этой серии 2018 года.
- Глава 1: Привет, мир!
- Глава 2: Шаблоны
- Глава 3: Веб-формы
- Глава 4: База данных
- Глава 5: Пользовательские логины
- Глава 6: Страница профиля и аватары
- Глава 7: Обработка ошибок
- Глава 8: Подписчики, контакты и друзья
- Глава 9: Разбивка на страницы
- Глава 10: Поддержка электронной почты
- Глава 11: Реконструкция
- Глава 12: Дата и время
- Глава 13: I18n и L10n
- Глава 14: Ajax
- Глава 15: Улучшение структуры приложения
- Глава 16: Полнотекстовый поиск
- Глава 17: Развертывание в Linux(Эта статья)
- Глава 18: Развертывание на Heroku (доступно 3 апреля 2018 года)
- Глава 19: Развертывание на Docker контейнерах (доступно 10 апреля 2018 года)
- Глава 20: Магия JavaScript (доступна 17 апреля 2018 года)
- Глава 21: Уведомления пользователей (доступно 24 апреля 2018 года)
- Глава 22: Справочные задания (доступны 1 мая 2018 года)
- Глава 23: Интерфейсы прикладного программирования (API) (доступно 8 мая 2018 г.)
Примечание 1: Если вы ищете старые версии данного курса, это здесь.
Примечание 2: Если вдруг Вы захотели бы выступить в поддержку моей (Мигеля) работы, или просто не имеете терпения дожидаться статьи неделю, я (Мигель Гринберг)предлагаю полную версию данного руководства (на английском языке) в виде электронной книги или видео. Для получения более подробной информации посетите learn.miguelgrinberg.com.
Эта глава — важная веха в жизни моего приложения Microblog, поскольку пришла пора обсудить, как оно может быть развернуто на рабочем сервере для доступа реальным пользователям.
Тема развертывания обширна, и по этой причине в рамках одной главы невозможно охватить все возможные варианты. Эта глава посвящена изучению традиционных вариантов хостинга, и в качестве объектов исследования я собираюсь использовать выделенный Linux-сервер под управлением Ubuntu, а также широко распространенный mini-computer Raspberry Pi. О других вариантах, таких как развертывание облаков и контейнеров, я расскажу в последующих главах.
Ссылки GitHub для этой главы: Browse, Zip, Diff.
Традиционный хостинг
Когда я говорю о «традиционном хостинге», я имею в виду, что приложение устанавливается вручную или через скриптовый установщик на штатный сервер. Процесс включает установку приложения, его зависимостей и production scale web server плюс настройку системы безопасности.
Первый вопрос, который нужно задать при развертывании собственного проекта — где найти сервер. В наши дни существует множество недорогих услуг хостинга. Например, за 5$ в месяц Digital Ocean, Linode или Amazon Lightsail сдадут вам в аренду виртуальный Linux-сервер (VPS) для проведения экспериментов по развертыванию. (Linode и Digital Ocean предоставляют своим серверам начального уровня 1 ГБ оперативной памяти, в то время как Amazon предоставляет только 512 МБ). Если вы предпочитаете попрактиковаться, не тратя денег, то Vagrant и VirtualBox-это два инструмента, которые в сочетании позволяют создать виртуальный сервер, подобный платному, на вашем собственном компьютере.
Что касается выбора операционной системы, то с технической точки зрения, это приложение может быть развернуто в любой из основных операционных систем, список, который включает в себя большое количество дистрибутивов Linux и BSD с открытым исходным кодом, а также коммерческую ОС X и Microsoft Windows (хотя OS X — гибридный вариант open-source/commercial, поскольку он основан на Darwin, производной BSD с открытым исходным кодом).
Поскольку ОС X и Windows являются настольными операционными системами, которые не оптимизированы для работы в качестве серверов, я собираюсь сразу отказаться от таких кандидатов. Выбор между операционной системой Linux или BSD во многом основывается на предпочтениях, поэтому я собираюсь выбрать самый популярный из двух, которой является Linux. Что касается дистрибутивов Linux, я думаю будет справедливо совершить выбор по популярности и продолжить с Ubuntu.
Сервер Ubuntu
Если вы заинтересовлись в этом развертывании вместе со мной, то вам, очевидно, понадобится сервер для работы. Я порекомендую вам два варианта приобретения сервера, один платный и один бесплатный. Если вы готовы потратить немного денег, вы можете получить учетную запись в Digital Ocean, Linode или Amazon Lightsail и создать виртуальный сервер Ubuntu 16.04. Вам будет достаточно использовать самый маленький серверный вариант, который на сегодняшний день, когда я пишу эту фразу, стоит 5 долларов США в месяц для всех трех поставщиков из приведенного выше перечня. Оплата почасовая, поэтому, если вы создадите сервер, поиграйте с ним в течение нескольких часов, а затем удалите его, вы заплатите только центами.
Бесплатная альтернатива основана на виртуальной машине, которую вы можете запускать на своем собственном компьютере. Чтобы использовать эту опцию, установите Vagrant и VirtualBox на свой компьютер, а затем создайте файл с именем Vagrantfile для описания спецификаций вашей виртуальной машины со следующим содержимым:
Vagrantfile: Vagrant configuration.
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.provider "virtualbox" do |vb|
vb.memory = "1024"
end
end
Этот файл настраивает сервер Ubuntu 16.04 с 1 ГБ ОЗУ, с которого вы сможете получить доступ с хост-компьютера по IP-адресу 192.168.33.10. Чтобы создать сервер, выполните следующую команду:
$ vagrant up
В документации по командной строке Vagrant, вы узнаете о других вариантах управления виртуальным сервером.
Использование SSH-клиента
Ваш сервер консольный, поэтому у вас не будет рабочего стола, как на вашем собственном компьютере. Вы должны будете подключиться к своему серверу через SSH-клиент и работать с ним через командную строку. Если вы используете Linux или Mac OS X, скорее всего, OpenSSH уже установлен. Если вы используете Microsoft Windows, Cygwin, Git и Windows Subsystem for Linux, то они то же предоставляют возможность использования OpenSSH, так что вы можете установить любой из этих вариантов.
Если вы используете виртуальный сервер стороннего поставщика, то при создании сервера вам был предоставлен IP-адрес. Вы можете открыть терминальный сеанс с вашим новым сервером с помощью следующей команды:
$ ssh root@
Вам будет предложено ввести пароль. В зависимости от службы, пароль может быть автоматически сгенерирован и показан Вам после создания сервера, или возможно вы сами, дали возможность выбрать свой собственный пароль.
Если вы используете Vagrant VM, вы можете открыть сеанс терминала с помощью команды:
$ vagrant ssh
Если вы используете Windows и Vagrant VM, обратите внимание, что вам нужно будет запустить указанную выше команду из оболочки, которая может вызывать команду ssh
из OpenSSH.
Логин без пароля (password-less)
Вы можете пропустить этот раздел если используете Vagrant VM, поскольку ваша виртуальная машина настроена правильно, чтобы использовать учетную запись, отличную от root, с именем ubuntu
без автоматического пароля от Vagrant.
Если вы используете виртуальный сервер, рекомендуется создать обычную учетную запись пользователя для выполнения своей работы по развертыванию и настроить эту учетную запись для входа в систему без использования пароля (password-less), что поначалу может показаться неудачным решением, но вы, увидите, что это не только более удобно, но и более безопасно.
Я собираюсь создать учетную запись пользователя с именем ubuntu
(вы можете использовать другое имя, если хотите). Чтобы создать эту учетную запись, войдите в корневую учетную запись своего сервера с помощью инструкций ssh
из предыдущего раздела, а затем введите следующие команды, чтобы создать пользователя, дать ему sudo
полномочия и, наконец, переключиться на него:
$ adduser --gecos "" ubuntu
$ usermod -aG sudo ubuntu
$ su ubuntu
Теперь я собираюсь настроить эту новую учетную запись ubuntu
на использование аутентификации public key, чтобы вы могли войти в систему без ввода пароля.
Оставьте сеанс терминала, который вы открыли на своем сервере, и запустите второй терминал на своем локальном компьютере. Если вы используете Windows, это должен быть терминал, с которого у вас есть доступ к команде ssh
, поэтому, вероятно, это будет bash
или подобное приглашение, а не родной Windows-терминал. В этом сеансе терминала проверьте содержимое ~/.ssh directory:
$ ls ~/.ssh
id_rsa id_rsa.pub
Если в списке каталогов есть файлы с именем id_rsa и id_rsa.pub, как указано выше, значит у вас уже есть ключ. Если у вас нет этих двух файлов или вообще нет каталога ~/.ssh, вам нужно создать свою пару ключей SSH, выполнив следующую команду, также входящую в набор инструментов OpenSSH:
$ ssh-keygen
Это приложение предложит вам ввести несколько значений, для которых я рекомендую вам принять значения по умолчанию, нажав Enter на всех приглашениях. Если вы знаете, что вы делаете, и хотите сделать иначе, то, как говориться, флаг вам в руки.
После выполнения этой команды у вас должны быть два файла, перечисленные выше. Файл id_rsa.pub-это ваш public key-открытый ключ, файл, который вы предоставляете третьим лицам для идентификации. Файл id_rsa-это ваш private key-приватный ключ, которым ни с кем делится не надо.
Теперь необходимо настроить открытый ключ в качестве authorized host на сервере. Распечатайте свой открытый ключ на экране терминала, который вы открыли на своем компьютере:
$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCjw....F8Xv4f/0+7WT miguel@miguelspc
Это будет очень длинная последовательность символов, возможно, охватывающая несколько строк. Необходимо скопировать эти данные в буфер обмена, а затем переключиться обратно в терминал на удаленном сервере, где будут выдаваться эти команды для хранения открытого ключа:
$ echo >> ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys
Теперь password-less должен работать. Идея состоит в том, что ssh
на вашем компьютере идентифицирует себя на сервере, выполняя криптографическую операцию, требующую секретного ключа. Затем сервер проверяет, что операция действительна с использованием открытого ключа.
Теперь вы можете выйти из своего сеанса ubuntu
, а затем из своего root
сеанса, а затем попытаться войти прямо в учетную запись ubuntu
с помощью:
$ ssh ubuntu@
На этот раз вам не нужно вводить пароль!
Защита сервера
Чтобы свести к минимуму риск взлома сервера, можно предпринять несколько шагов, направленных на закрытие ряда потенциальных дверей, через которые злоумышленник может получить доступ.
Первое изменение, которое необходимо сделать, это отключить root логины через SSH. Теперь у вас есть password-less доступ к учетной записи ubuntu
, и вы можете запускать команды администратора с этой учетной записи через sudo
(от имени), так что действительно нет необходимости предоставлять учетную запись root. Чтобы отключить root логины, необходимо отредактировать файл /etc/ssh/sshd_config на вашем сервере. Возможно vi
и nano
(текстовые редакторы) уже установлены на вашем сервере и вы можете использовать их для редактирования файлов (если вы не знакомы с любым из них, попробуйте nano
первым). Вам понадобится префикс вашего редактора с sudo, потому что конфигурация SSH не доступна для обычных пользователей (например, sudo vi /etc/ssh/sshd_config
). Необходимо изменить одну строку в этом файле:
/etc/ssh/sshd_config: Disable root logins.
PermitRootLogin no
После завершения редактирования конфигурации SSH необходимо перезапустить службу, чтобы изменения вступили в силу:
$ sudo service ssh restart
Третье изменение, которое надо сделать — установить брандмауэр. Это программное обеспечение, которое блокирует доступ к серверу на порты, которые не разрешены явно:
$ sudo apt-get install -y ufw
$ sudo ufw allow ssh
$ sudo ufw allow http
$ sudo ufw allow 443/tcp
$ sudo ufw --force enable
$ sudo ufw status
Эти команды устанавливают UFW, простенький брандмауэр и настраивают его на разрешение только внешнего трафика на портах 22 (SSH), 80 (http) и 443 (HTTPS). Любые другие порты будут закрыты.
Установка Базовых Зависимостей
Если вы следовали моим советам и установили сервер на Ubuntu 16.04, то у вас уже есть система с полной поддержкой Python 3.5, который я собираюсь использовать для развертывания.
Итак, считаем, что базовый интерпретатор Python предварительно установлен на вашем сервере, но есть некоторые дополнительные пакеты, которые, скорее всего, отсутствуют, а также есть несколько других пакетов за пределами Python, которые будут полезны при создании надежного, готового работе развертыванию. Для сервера базы данных я собираюсь переключиться с SQLite на MySQL. postfix — это агент передачи почты, который я буду использовать для отправки электронной почты. Инструмент supervisor будет следить за процессом сервера Flask и автоматически перезапускать его, если он когда-либо упадет, или если сервер перезагрузится. Сервер nginx будет принимать все запросы, поступающие из вне, и перенаправлять их в приложение. Наконец, я собираюсь использовать git в качестве инструмента для загрузки приложения непосредственно из своего репозитория git.
$ sudo apt-get -y update
$ sudo apt-get -y install python3 python3-venv python3-dev
$ sudo apt-get -y install mysql-server postfix supervisor nginx git
Эти установки запускаются в основном без присмотра, но в какой-то момент, на третьем оператор установки, вам будет предложено выбрать пароль root для службы MySQL, и ещё будет задано несколько вопросов относительно установки пакета postfix, в ответах на которые вы можете принять значения по умолчанию.
Обратите внимание, что для этого развертывания я предпочитаю не устанавливать Elasticsearch. Для этой услуги требуется большой объем оперативной памяти, поэтому она жизнеспособна, если у вас большой сервер с объемом памяти более 2 ГБ. Чтобы избежать проблем с нехваткой памяти на сервере, я оставлю функциональность поиска. Если у вас достаточно большой сервер, вы можете загрузить официальный пакет .deb с сайта Elasticsearch и следовать их инструкциям по установке, чтобы добавить его на свой сервер. Ещё важный момент! Пакет Elasticsearch, доступный в репозитории пакета Ubuntu 16.04, слишком стар и не работает, вам нужна версия 6.x или новее.
Следует также отметить, что установки postfix по умолчанию, вероятно, недостаточно для отправки электронной почты в рабочей среде. Чтобы избежать спама и вредоносных писем, многим серверам требуется, чтобы сервер отправителя идентифицировал себя с помощью расширений безопасности, что означает, по крайней мере, вы должны иметь доменное имя, связанное с вашим сервером. Если вы хотите узнать, как полностью настроить почтовый сервер, чтобы он прошел стандартные тесты безопасности, см. Следующие руководства по Digital Ocean:
- Postfix Configuration
- Adding an SPF Record
- DKIM Installation and Configuration
Установка приложения
Теперь я собираюсь использовать git
для загрузки исходного кода Microblog из моего репозитория GitHub. Я бы поорекомендовал вам почитать git for beginners, если Вы не знакомы с системой управления версиями git.
Прим.переводчика: три хороших руководств для изучающих Git на русском языке:
- Git the simple guide — простое руководство по работе с git. Но для кого-то этого материала может не хватить, поскольку там описано все очень кратко и только основные моменты.
- Pro Git — исчерпывающая книга по Git, которую можно купить на Амазоне или читать онлайн / скачать бесплатно.
- Git How To — это интерактивный тур, который познакомит вас с основами Git. Тур создан с пониманием того, что лучшим способом научиться чему-нибудь — сделать это своими руками.
Чтобы загрузить приложение на сервер, убедитесь, что вы находитесь в домашнем каталоге пользователя ubuntu
, а затем запустите:
$ git clone https://github.com/miguelgrinberg/microblog
$ cd microblog
$ git checkout v0.17
Эта последовательность команд устанавливает код на вашем сервере и синхронизирует его с этой главой. Если вы ведете свою версию этого учебного кода в своем репозитории git, вы можете изменить URL-адрес репозитория на свой, и в этом случае вы можете пропустить команду git checkout.
Теперь мне нужно создать виртуальную среду и заполнить ее всеми зависимостями пакета, которые я для удобства сохранил в файле requirements.txt в главе 15:
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ pip install -r requirements.txt
В дополнение к общим требуемым пакетам в requirements.txt, я собираюсь использовать еще два, которые относятся только к этой среде, поэтому они не включены в файл requirements. Пакет gunicorn
-это веб-сервер для приложений на Python. Пакет pymysql
содержит драйвер MySQL, позволяющий SQLAlchemy работать с базами данных MySQL:
(venv) $ pip install gunicorn pymysql
Мне нужно создать файл .env со всеми необходимыми переменными среды:
/home/ubuntu/microblog/.env: Конфигурация среды.
SECRET_KEY=52cb883e323b48d78a0a36e8e951ba4a
MAIL_SERVER=localhost
MAIL_PORT=25
DATABASE_URL=mysql+pymysql://microblog:@localhost:3306/microblog
MS_TRANSLATOR_KEY=
Этот файл .env слегка похож на пример, который я показал в главе 15, но я использовал случайную строку для SECRET_KEY. Для генерации случайной строки, я использовал следующую команду:
python3 -c "import uuid; print(uuid.uuid4().hex)
Для переменной DATABASE_URL
я определил URL MySQL. Я покажу вам, как настроить базу данных в следующем разделе.
Мне нужно установить переменную среды FLASK_APP
в точку входа приложения, чтобы команда flask
работала, но эта переменная должна быть определена до анализа файла .env, поэтому её необходимо установить вручную. Чтобы избежать необходимости проделывать это каждый раз, я собираюсь добавить её в нижнюю часть ~/.profile для учетной записи ubuntu
, так что она будет устанавливаться автоматически каждый раз при моем входе:
$ echo "export FLASK_APP=microblog.py" >> ~/.profile
Если вы выйдете из системы и вернетесь, значение FLASK_APP для вас будет уже установлено. Вы можете подтвердить, что значение определено с помощью flask --help
. Если вспомогательное сообщение показывает команду translate
, добавленную приложением, то значит приложение было найдено.
И теперь, когда команда flask
функциональна, я могу скомпилировать языковые переводы:
(venv) $ flask translate compile
Настройка MySQL
База данных sqlite, которую я использовал во время разработки, отлично подходит для простых приложений, но при развертывании полномасштабного веб-сервера, который потенциально может обрабатывать несколько запросов одновременно, лучше использовать более надежную СУБД. По этой причине я собираюсь создать базу данных MySQL, которую я буду называть microblog
.
Для управления сервером баз данных используется команда mysql
, которая должна быть уже установлена на вашем сервере:
$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.19-0ubuntu0.16.04.1 (Ubuntu)
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
Обратите внимание, что вам нужно будет ввести root-пароль MySQL, который вы выбрали при установке MySQL, чтобы получить доступ к командной строке MySQL.
Это команды, которые создают новую базу данных под названием microblog
и пользователя с тем же именем с полным доступом к ней:
mysql> create database microblog character set utf8 collate utf8_bin;
mysql> create user 'microblog'@'localhost' identified by '';
mysql> grant all privileges on microblog.* to 'microblog'@'localhost';
mysql> flush privileges;
mysql> quit;
Вам нужно будет заменить
паролем по вашему выбору. Это будет пароль для пользователя базы данных microblog
, так что будет правильно, чтобы он отличался от пароля для пользователя root. Пароль для пользователя microblog
должен совпадать с паролем, включенным в переменную DATABASE_URL
файл .env.
Если конфигурация базы данных правильная, можно запускать миграции базы данных, создающие все таблицы:
(venv) $ flask db upgrade
Прежде чем продолжить, убедитесь, что приведенная выше команда выполнена без ошибок.
Настройка Gunicorn и Supervisor
Когда вы запускаете сервер командой flask run
, вы используете веб-сервер, который поставляется с Flask. Этот сервер полезен во время разработки, но он не является хорошим выбором для использования на рабочем сервере, потому что он не был построен с учетом производительности и надежности. Вместо сервера разработки Flask для этого развертывания я решил использовать gunicorn, который также является чистым веб-сервером Python, но в отличие от Flask, это надежный production сервер, который используется многими людьми, в то же время он очень прост в использовании.
Для запуска Микроблога под gunicorn вы можете использовать следующую команду:
(venv) $ gunicorn -b localhost:8000 -w 4 microblog:app
Опция -b
сообщает gunicorn, что установлен порт 8000 внутреннего сетевого интерфейса для прослушки запросов. Обычно рекомендуется запускать веб-приложения Python без внешнего доступа, а затем иметь очень быстрый веб-сервер, оптимизированный для обслуживания статических файлов, принимающих все запросы от клиентов. Этот быстрый веб-сервер будет обслуживать статические файлы напрямую и перенаправлять любые запросы, предназначенные для приложения, на внутренний сервер. Я покажу вам, как настроить nginx в качестве публичного сервера в следующем разделе.
Параметр -w
определяет, сколько рабочих процессов будет работать с gunicorn. Наличие четырех процессов позволяет приложению обрабатывать до четырех клиентов одновременно, что для веб-приложения обычно достаточно для обработки приличного количества клиентов, так как не все из них постоянно запрашивают контент. В зависимости от объема ОЗУ, имеющегося на сервере, может потребоваться настроить количество процессов, чтобы не исчерпать память.
Аргумент microblog:app
сообщает gunicorn, как загрузить экземпляр приложения. Имя перед двоеточием-это модуль, содержащий приложение, А имя после двоеточия-это имя этого приложения.
Хотя gunicorn очень прост в настройке, запуск из командной строки на самом деле не является хорошим решением для рабочего сервера. Я хочу, чтобы он работал в фоновом режиме и находился под постоянным контролем, потому что если по какой-либо причине сервер падает и выходит, хотелось бы убедиться, что новый сервер автоматически запустится, чтобы занять его место. Кроме того, при перезагрузке компьютера, сервер должен запускаться автоматически, без необходимости входить в систему и запускать все самостоятельно. Я собираюсь использовать пакет supervisor, который я установил выше для этих целей.
Утилита supervisor использует файлы конфигурации, которые сообщают ей, какие программы отслеживать и как перезапускать их при необходимости. Файлы конфигурации должны храниться в /etc/supervisor/conf.d. Вот файл конфигурации для Микроблога, который я собираюсь назвать microblog.conf:
/etc/supervisor/conf.d/microblog.conf: Supervisor configuration.
[program:microblog]
command=/home/ubuntu/microblog/venv/bin/gunicorn -b localhost:8000 -w 4 microblog:app
directory=/home/ubuntu/microblog
user=ubuntu
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
Настройки command
, directory
и user
сообщают супервизору, как запустить приложение. autostart
и autorestart
настройки автоматической перезагрузки из-за запуска компьютера или сбоя. Опции stopasgroup
и killasgroup
гарантируют, что когда супервизору необходимо остановить приложение, чтобы перезапустить его, он также достигнет все дочерние процессы процесса gunicorn верхнего уровня.
После записи этого файла конфигурации необходимо перезагрузить службу супервизора для его импорта:
$ sudo supervisorctl reload
И точно так же, веб-сервер gunicorn должен быть запущен и проверен!
Настройка Nginx
Сервер приложений microblog на базе gunicorn теперь работает на частном порту 8000. То, что мне нужно сделать сейчас, чтобы предоставить приложение внешнему миру, — это включить мой общедоступный веб-сервер на портах 80 и 443, два порта, которые я открыл на брандмауэре для обработки веб-трафика приложения.
Я хочу, чтобы это было безопасное развертывание, поэтому я собираюсь настроить порт 80 для пересылки всего трафика на порт 443, который будет зашифрован. Итак, я собираюсь начать с создания SSL-сертификата. Сейчас я собираюсь создать self-signed SSL certificate, который подходит для тестирования всего, но не подходит для реального развертывания, потому что веб-браузеры будут предупреждать пользователей, что сертификат не был выдан доверенным центром сертификации. Команда для создания сертификата SSL для микроблога:
$ mkdir certs
$ openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \
-keyout certs/key.pem -out certs/cert.pem
Команда запросит у вас некоторую информацию о вашем приложении и о себе. Это информация, которая будет включена в сертификат SSL, и что веб-браузеры будут показывать пользователям, если они захотят увидеть его. Результатом выполнения приведенной выше команды будет два файла с именем key.pem
и cert.pem
, который я разместил в подкаталоге certs корневого каталога Микроблога.
Чтобы веб-сайт обслуживался nginx, необходимо написать для него файл конфигурации. В большинстве установок nginx этот файл должен находиться в каталоге /etc/nginx/sites-enabled directory. Nginx устанавливает тестовый сайт в этом месте, который мне не нужен, поэтому я собираюсь начать с его удаления:
$ sudo rm /etc/nginx/sites-enabled/default
Ниже вы можете увидеть конфигурационный файл nginx для Microblog, который входит в /etc/nginx/sites-enabled/microblog:
/etc/nginx/sites-enabled/microblog: Nginx configuration.
server {
# прослушивание порта 80 (http)
listen 80;
server_name _;
location / {
# перенаправлять любые запросы на один и тот же URL-адрес, как на https
return 301 https://$host$request_uri;
}
}
server {
# прослушивание порта 443 (https)
listen 443 ssl;
server_name _;
# расположение self-signed SSL-сертификата
ssl_certificate /home/ubuntu/microblog/certs/cert.pem;
ssl_certificate_key /home/ubuntu/microblog/certs/key.pem;
# запись доступа и журналы ошибок в /var/log
access_log /var/log/microblog_access.log;
error_log /var/log/microblog_error.log;
location / {
# переадресация запросов приложений на сервер gunicorn
proxy_pass http://localhost:8000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static {
# обрабатывать статические файлы напрямую, без пересылки в приложение
alias /home/ubuntu/microblog/static;
expires 30d;
}
}
Конфигурация nginx далека от тривиальной, но я добавил несколько комментариев, чтобы, по крайней мере, вы знали, что делает каждая секция. Если вы хотите получить информацию о конкретной директиве, обратитесь к официальной документации nginx.
После добавления этого файла вам нужно передать nginx инструкцию по перезагрузке конфигурации, для его активации:
$ sudo service nginx reload
Теперь приложение должно быть развернуто. В веб-браузере можно ввести IP-адрес сервера (или 192.168.33.10, если вы используете виртуальную машину Vagrant), который будет подключаться к приложению. Поскольку вы используете самозаверяющий сертификат, вы получите предупреждение от веб-браузера, которое вам придется отклонить.
После завершения развертывания с приведенными выше инструкциями для собственных проектов настоятельно рекомендуется заменить самозаверяющий сертификат реальным, чтобы браузер не предупреждал пользователей о вашем сайте. Для этого вам сначала нужно купить доменное имя и настроить его на IP-адрес вашего сервера. После того, как у вас появится домен, вы можете запросить бесплатный Let’s Encrypt сертификат SSL. Я написал подробную статью в своем блоге о том, как запустить Приложение Flask через HTTPS.
Развертывание обновлений приложений
В заключении этой главы относительно развертывания на основе Linux я хочу обсудить вопрос, как обрабатывать обновления приложений. Исходный код приложения устанавливается на сервере через git
, поэтому всякий раз, когда вы хотите обновить приложение до последней версии, вы можете просто запустить git pull
, чтобы загрузить новые коммиты, которые были сделаны с момента предыдущего развертывания.
Но, конечно, загрузка новой версии кода не будет вызывать обновление. Серверные процессы, выполняющиеся в данный момент, продолжат работать со старым кодом, который уже был прочитан и сохранен в памяти. Чтобы инициировать обновление, необходимо остановить текущий сервер и запустить новый, чтобы заставить весь код быть прочитанным снова.
Выполнение обновления в целом сложнее, чем просто перезапуск сервера. Возможно, потребуется применить миграцию базы данных или скомпилировать новые языковые переводы, поэтому в действительности процесс обновления включает последовательность команд:
(venv) $ git pull # Скачать новую версию
(venv) $ sudo supervisorctl stop microblog # Остановка текущего сервера
(venv) $ flask db upgrade # Обновление базы данных
(venv) $ flask translate compile # Обновление переводов
(venv) $ sudo supervisorctl start microblog # Запуск нового сервера
Raspberry Pi Хостинг
Raspberry Pi-это недорогой революционный маленький компьютер Linux, который имеет очень низкое энергопотребление, поэтому это идеальное устройство для размещения домашнего веб-сервера, который может быть ОНЛАЙН 24/7, не связывая ваш настольный компьютер или ноутбук. Есть несколько дистрибутивов Linux, которые работают на Raspberry Pi. Мой выбор Raspbian, который является официальным дистрибутивом от Raspberry Pi Foundation.
Чтобы подготовить Raspberry Pi, я собираюсь установить свежий выпуск Raspbian. Я буду использовать версию raspbian Stretch Lite в сентябре 2017 года, но к тому времени, когда вы прочтете это, скорее всего, появятся новые версии, поэтому проверьте официальную страницу загрузки, чтобы получить самый последний релиз.
Образ Raspbian должен быть установлен на SD-карту, которую вы затем подключаете к Raspberry Pi, чтобы он мог загружаться с ним. Инструкции по копированию образа Raspbian на SD-карту из Windows, Mac OS X и Linux доступны на сайте Raspberry Pi.
При первой загрузке Raspberry Pi делайте это при подключении к клавиатуры и монитора, так что бы вы могли сделать настройку. По крайней мере, вы должны включить SSH, чтобы можно было войти в систему со своего компьютера для более удобного выполнения задач развертывания.
Как и Ubuntu, Raspbian является производной Debian, поэтому приведенные выше инструкции для Ubuntu Linux по большей части работают так же, как и для Raspberry Pi. Однако вы можете пропустить некоторые шаги, если планируете запускать небольшое приложение в домашней сети без внешнего доступа. Например, вам может не понадобиться брандмауэр или логины без пароля. И вы можете использовать SQLite вместо MySQL на таком маленьком компьютере. Вы можете отказаться от использования nginx и просто заставить сервер gunicorn слушать запросы клиентов напрямую. Вам, вероятно, понадобится только один процесс gunicorn. Служба супервизора полезна для обеспечения того, чтобы приложение всегда было в порядке, поэтому я советовал бы использовать его и на Raspberry Pi.
Туда Сюда