Установка flask-приложения на веб-сервер Ubuntu + Apache

В данной статье рассматривается пример-инструкция разворачивания созданного на Flask сайта на удаленном виртуальном сервере (VPS) с операционной системой Ubuntu и программным веб-сервером Apache.

Для запуска flask-приложений данный способ далеко не единственный. Нередко используют связку Gunicorn и Nginx. Однако, если на одном VPS размещается несколько сайтов, и не все созданы на Python, бывает проще использовать Apache.

При этом связь между Apache и flask-приложением обеспечивает специальный модуль, представляющий собой WSGI-сервер, интегрированный в Apache, то есть является его модулем, а не пакетом Python.

В данной статье мы исходим из того, что читатель слабо представляет, как работать на удаленном компьютере и настраивать веб-сервера. Поэтому с целью упрощения следующие действия будут опущены: обновление ПО операционной системы, создание обычного пользователя, доступ по протоколу SSH по ключу, размещение нескольких сайтов на одном веб-сервере. Выполнить их для опытного пользователя не составит труда.

Также не будет создаваться виртуальное окружение Python. Пакет flask установим в саму систему.

Сначала будем обращаться к сайту по IP на случай, если вы не регистрировали домен. В конце оговорим, как прикрепить домен к IP и выпустить сертификат безопасности. Ознакомиться с общими вопросами "что такое хостинг, домен и как регистрировать последний" можно в статье "Размещение сайта в Интернет. Домен и хостинг".

В качестве хостинг-провайдера будем использовать https://beget.com, так как в его варианте VPS есть файловый менеджер с веб-интерфейсом, терминал в панели управления. Это позволит отстраниться от особенностей вашей операционной системы, не устанавливать на нее дополнительное ПО для доступа к удаленному серверу, избежать объяснения принципов работы в консольных редакторах и др. Также посуточная оплата (на 2023 г. минимальная конфигурация сервера стоит 7 руб/сутки) дает возможность быстро отказаться от услуги, как только она вам станет не нужна.

При регистрации аккаунта Бегет следует выбирать "VPS 7 Р". В разделе "Облако" личного кабинета выберите Создать → Виртуальный сервер. Укажите конфигурацию сервера, из готовых решений ‒ Ubuntu одной из последних версий. Далее кликните по "Задать пароль", сохраните готовый или введите свой.

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

Необходимо ввести логин и пароль. У нас есть только администратор системы, поэтому в качестве логина используется root. Пароль при вводе не отображается. В данном случае (так бывает не всегда) копирование не работает и вводить придется вручную.

В случае успешного входа в систему вы увидите приглашение вроде этого: root@jtbajsd:~#

В Linux есть команда clear, которая позволяет очищать экран терминала. Введите это слово после приглашения и нажмите Enter (выполнение команды). Позже вы можете использовать clear в любой момент.

Первое, что мы должны сделать, ‒ это установить веб-сервер Apache. Выполним команду:

apt install apache2

В процессе установки ПО появится вопрос: "Do you want to continue? [Y/n]". В качестве ответа надо ввести букву Y или y.

После завершения установки сверните окно терминала. На странице описания вашего сервера в виджете "Реквизиты доступа" скопируйте IP и вставьте его в адресную строку браузера (откройте для этого новую вкладку браузера). Если Apache правильно работает, вы увидите страницу с заголовком "Apache2 Default Page".

Вернемся в терминал и установим модуль wsgi-сервера (если в процессе установки появится сообщение, нажмите Enter):

apt install libapache2-mod-wsgi-py3

Третье ПО, которое надо установить, ‒ микрофреймворк Flask (Python в Ubuntu уже должен быть по-умолчанию).

pip3 install Flask или apt install python3-flask

На своем локальном компьютере, перед тем как создать архив для выгрузки на удаленный сервер, в корневом каталоге проекта (flask-приложения, сайта) создадим файл с расширением .wsgi и таким содержанием:

import sys
sys.path.insert(0, '/var/www/html/')
 
from project import app as application

Здесь /var/www/html/ ‒ адрес каталога на удаленном сервере, в котором будут размещены файлы нашего сайта. project ‒ имя основного python-файла приложения без расширения. app ‒ имя переменной, которой присваивается экземпляр Flask. Если у вас каталог и имена другие, указываете их. Слово application при данном способе настройки веб-сервера должно остаться как есть. Если вы назвали python-файл app.py, а переменную экземпляра Flask ‒ app, то импорт будет таким: from app import app as application.

Имя файла .wsgi может быть любым. Важно запомнить его, оно понадобится позже. Пусть будет: siteapp.wsgi. Примечание: при использовании WSGIDaemonProcess нельзя для разных сайтов, размещенных на одном веб-сервере, одинаково именовать файлы .wsgi.

В каталоге вашего проекта следует выделить все файлы (исключая каталог виртуального окружения Python и __pycache__) и запаковать их в архив, например, .zip. Обратите внимание, в данном случае в архив упаковывается не сам каталог проекта, а содержащиеся в нем файлы и папки.

Вернитесь на страницу виртуального сервера в аккаунте Бегет. Кликните там по "Файловый менеджер". При этом откроется еще одна вкладка браузера. Обе половины приложения отражают структуру файлов вашего удаленного виртуального сервера. Бывает удобно работать на одной половине в одном каталоге, а на другой ‒ в другом.

Перейдите в папку /var/www/html/. Здесь находится файл index.html, содержимое которого мы видели в браузере при обращении по IP. Этот файл можно удалить.

Загрузите сюда созданный на локальном компьютере архив и распакуйте его (кликните по нему правой кнопкой мыши и выберите "Распаковать Архив").

Перейдите в каталог /etc/apache2/sites-available/. Кликните правой кнопкой мыши по файлу 000-default.conf и выберите "Правка".

Примечание для опытных. Если вы "работаете по живому" ‒ не меняете сервер и переводите работающий сайт, уже имеющий сертификат безопасности, на Flask, то править надо конфигурационный файл для порта 443, а не 80.

Вместо строки (ее можно закомментировать решеткой)

DocumentRoot /var/www/html

Вставьте строку, в которой указан путь до вашего wsgi-файла:

WSGIScriptAlias / /var/www/html/siteapp.wsgi

Также под ней следует добавить

<Directory /var/www/html>
    Order allow,deny
    allow from all
</Directory>

Сохраните и закройте файл.

Настройки не вступают в силу сразу. Требуется перезапустить веб-сервера Apache. Для этого вернемся в терминал и выполним команду:

systemctl restart apache2

Если после этого вы перезагрузите веб-страницу по вашему IP-адресу, то получите ошибку "Internal Server Error". Она связана с тем, что владельцем файлов flask-приложения является пользователь root. Поскольку мы не создавали обычного пользователя, то укажем www-data. Под ним Apache может получить доступ к файлам:

chown -R www-data:www-data /var/www/html/

После этого сайт должен заработать.

Если у вас есть зарегистрированный домен, то чтобы обращения к нему перенаправлять на ваш веб-сервер, надо в разделе DNS личного кабинета Бегет указать для данного домена IP сервера.

Если домен был приобретен у другого регистратора, то перед тем как править IP его надо добавить в разделе "Домены и поддомены", скопировать здесь DNS Бегета (указаны слева) и в личном кабинете другого регистратора указать эти DNS. При этом доступ к сайту по имени домена станет доступен не через несколько минут, а возможно несколько часов.

Сайт будет доступен по адресам типа http://имя_домена.зона и http://www.имя_домена.зона. Обратите внимание, что используется протокол HTTP, а не HTTPS. По второму сайт не откроется.

Если на одном VPS будет несколько сайтов, то для каждого создается свой конфигурационный файл Apache, а сам веб-сервер должен знать, какую конфигурацию применять при получении того или иного адреса. Поэтому в нашем файле 000-default.conf будет не лишним указать доменные имена. Раскомментируйте (уберите решетку) строку:

# ServerName www.example.com

Вместо адреса www.example.com впишите ваш домен. Также добавьте строку ServerAlias. Пример:

ServerName flask.website 
ServerAlias www.flask.website

Перезапустите Apache, иначе не сможете выпустить сертификат.

Чтобы сайт стал доступен по HTTPS, надо установить в систему сертификат безопасности. Существует certbot ‒ специальная программа, которая автоматизирует выпуск и настройку сертификата Let’s Encrypt. Сначала надо установить ее:

apt install certbot python3-certbot-apache

Непосредственно выпуск сертификата выполняется командой:

certbot --apache -d flask.website -d www.flask.website

где вместо flask.website надо указать ваше доменное имя.

В процессе выпуска от вас потребуется ввести емейл, согласиться со сроком оказания услуг, отказаться от рассылки. Могут быть варианты в зависимости от того, выпускали ли вы раньше сертификат и действителен ли он еще (выбрать 1 или 2).

В случае удачного выпуска, среди прочего вы увидите сообщение "Congratulations! You have successfully …", а сайт станет доступен по адресам https://имя_домена.зона и https://www.имя_домена.зона.

При этом в каталоге /etc/apache2/site-available/ появится файл 000-default-le-ssl.conf. Если вы его не видите в файловом менеджере, нажмите F5. В новый файл (используется при обращении к порту 443, то есть по HTTPS) скопированы настройки из конфигурационного файла, который мы правили (для порта 80, HTTP), и добавлена информация о том, где находятся сертификаты.

В файл 000-default.conf появятся подобные строки:

RewriteEngine on
RewriteCond %{SERVER_NAME} =flask.website [OR]
RewriteCond %{SERVER_NAME} =www.flask.website
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

Это команды перенаправления. При обращении к сайту по адресам, начинающимся с http://…, сервер будет перенаправлять на https://… Можете убедиться в этом, вводя в адресной строке браузера http://имя_домена.зона/путь. Вас должно перебрасывать на https://имя_домена.зона/путь.

Однако у нас нет редиректа с www не без www, или наоборот. То есть страница доступна и по адресу https://имя_домена.зона/путь и по https://www.имя_домена.зона/путь. Это плохо с точки зрения оптимизации сайта для поисковых систем. Адрес документа должен определяться однозначно.

Один из вариантов решения проблемы ‒ добавить в конфигурационный файл для порта 443 (перед закрывающим тегом VirtualHost) такие команды:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.flask.website
RewriteRule ^ https://flask.website%{REQUEST_URI} [R=301,L]

Это перенаправление с www на без www.

В файл конфигурации можно добавить больше инструкций (если вы его изменяете, не забывайте перезапускать Apache). Делать это следует после установки сертификата, иначе возникает ошибка при выпуске, так как имя для WSGIDaemonProcess должно быть уникально и в разных файлах конфигурации даже одного сайта различаться. А при выпуске сертификата происходит копирование настроек.

WSGIDaemonProcess siteapp user=www-data group=www-data threads=5
WSGIScriptAlias / /var/www/html/siteapp.wsgi
 
<Directory /var/www/html>
    WSGIProcessGroup siteapp
    WSGIApplicationGroup %{GLOBAL}
    Order allow,deny
    allow from all
</Directory>

Flask для начинающих




Все разделы сайта