Материал подготовлен командой Simple-Server для администраторов VPS и выделенных серверов. Команды и пути проверяйте на тестовой машине перед production.
Кратко о задаче
Для начала убедитесь, что Python отсутствует в системе:
После этого рекомендуется обновить список доступных для загрузки пакетов:
Далее установим последнюю версию Python и несколько связанных с ним зависимостей — пакетный менеджер, библиотеку с высокоуровневыми типами и модуль для создания виртуальных сред.
sudo apt install python3 python3-pip python3-dev python3-venvТеперь, если запустить Python, откроется интерпретатор:
Для проверки введем простой код и выполним его:
print("Hello, Simple-Server")В консоли появится результат выполнения:
2. Установка и конфигурация сервера Nginx
Nginx в нашем примере будет использоваться как «обратный прокси-сервер», который принимает запросы пользователей и отдает их далее на обработку ASGI-серверу Uvicorn в FastAPI-приложение.
В нашем блоге есть подробная инструкция о том, как установить веб-сервер Nginx на операционную систему Ubuntu.
Сперва обновляется список репозиториев:
Далее выполняется загрузка и установка Nginx:
После этого нужно внести изменения в системный файрвол UFW (Uncomplicated Firewall), сделав доступным 80-й порт для HTTP-соединения:
sudo ufw allow 'Nginx HTTP'Конфигурационный файл nginx.conf расположен в каталоге /etc/nginx/. Мы полностью перезапишем его содержимое, задав минимальные настройки, необходимые для перенаправления запросов на FastAPI:
daemon on; # Nginx будет работать как фоновая служба
worker_processes 2;
user www-data;
events {
use epoll;
worker_connections 1024;
}
error_log /var/log/nginx/error.log;
http {
server_tokens off;
include mime.types;
charset utf-8;
access_log logs/access.log combined;
server {
listen 80;
server_name www.ДОМЕН.ЗОНА ДОМЕН.ЗОНА;
# Вместо ДОМЕН.ЗОНА указывается адрес вашего веб-сервера
# Например, site.ru или site.com
# Либо можно использовать localhost
location / {
proxy_pass http://127.0.0.1:8000; # указанный порт должен соответствовать порту сервера Uvicorn
proxy_set_header Host $host; # передаем заголовок Host, содержащий целевой IP и порта сервера.
proxy_set_header X-Real-IP $remote_addr; # передаем заголовок с IP-адресом пользователя
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # передаем всю последовательность адресов, через которые прошел запрос
}
}
}Обратите внимание, что мы упростили структуру конфигурационных файлов, отказавшись от использования директорий /etc/nginx/sites-available/ и /etc/nginx/sites-enabled/, а также дополнительных файлов из /etc/nginx/conf.d/.
Минимальная конфигурация важна не только для нашего примера. Она также позволяет убрать лишние элементы сервера, не выходя за пределы потребностей проекта. Это повышает безопасность сервера и улучшает понимание его работы.
Кстати, если вы планируете использовать SSL-сертификат на своем сервере, у Simple-Server есть отдельная инструкция по установке SSL-сертификата на Nginx.
Чтобы проверить корректность конфигурационного файла, выполните следующую команду:
Флаг -t предназначен для тестирования файла конфигурации — Nginx анализирует синтаксис и проверяет на существование указанные в файлы. Более подробно о флагах можно узнать в официальной справке.
Так как Nginx работает в фоновом режиме как служба, после установки он уже должен быть запущен. Однако чтобы применить новую конфигурацию, веб-сервер нужно принудительно перезапустить:
sudo systemctl restart nginxДля справки, есть и другая команда, которая перезапускает Nginx, корректно завершая его процессы:
sudo systemctl reload nginx3. Создание простого приложения FastAPI
Сначала мы создадим папку fastapp под наше FastAPI-приложение в системном каталоге /var, который рекомендуется использовать для размещения файлов веб-серверов:
Далее перейдем в созданный каталог:
Теперь создадим локальную изолированную виртуальную среду Python — именно для этого мы предварительно установили пакет python3-venv:
Для активации среды нужно выполнить специальный сценарий, который появился вместе с остальными папками после создания виртуальной среды:
Используя пакетный менеджер pip, мы загрузим и установим библиотеку FastAPI, а также ASGI-сервер Uvicorn:
pip install fastapi uvicornТеперь мы можем запустить приложение для теста, используя uvicorn. Хост будет размещен локально на стандартном порту:
uvicorn main:app --host 127.0.0.1 --port 8000 --reloadРазберем немного подробнее эту команду:
-
После флага
--hostмы указываем IP-адрес локального хоста (localhost). -
После флага
--portмы указываем номер свободного порта для TCP/UDP-соединения. Обратите внимание, что это не 80 порт HTTP-протокола. -
Параметр
mainуказывает на название запускаемого модуля. По умолчанию это название python-файла. -
Параметр
appуказывает на экземпляр приложения, который создается внутри кода. -
Флаг
--reloadуказывает Uvicorn самостоятельно отслеживать изменения в исходных файлах и автоматически перезапускать сервер. Этот флаг следует использовать только во время разработки.
После флага --host мы указываем IP-адрес локального хоста (localhost).
После флага --port мы указываем номер свободного порта для TCP/UDP-соединения. Обратите внимание, что это не 80 порт HTTP-протокола.
Параметр main указывает на название запускаемого модуля. По умолчанию это название python-файла.
Параметр app указывает на экземпляр приложения, который создается внутри кода.
Флаг --reload указывает Uvicorn самостоятельно отслеживать изменения в исходных файлах и автоматически перезапускать сервер. Этот флаг следует использовать только во время разработки.
Стандартная конфигурация возвращает JSON-объект с сообщением «Hello World». Чтобы убедиться в этом, можно сделать curl-запрос:
curl -X "GET" "http://localhost:8000"Флаг -X здесь равнозначен более длинной форме --request, которая необходима для изменения метода HTTP-запроса на GET.**
**
Откроем файл main.py и заменим его содержимое кодом нашего импровизированного приложения:
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from fastapi.responses import JSONResponse
app = FastAPI() # создаем экземпляр приложения через конструктор
# функция-обработчик корневого GET-запроса вместе с методом-декоратором app.get
@app.get("/")
async def get_root():
page = "<h1>Hello World!</h1>" # текст ответа сервера
return HTMLResponse(content=page)
# функция-обработчик импровизированного GET-запроса страницы вместе с методом-декоратором app.get
@app.get("/pages/{page_number}")
async def get_page(page_number):
return JSONResponse({"page_number": page_number})
# функция-обработчик импровизированного GET-запроса пользователя вместе с методом-декоратором app.get
@app.get("/members/{member_number}")
async def get_page(member_number):
return JSONResponse({"member_number": member_number})
# функция-обработчик импровизированного POST-запроса пользователя вместе с методом-декоратором app.post
@app.post("/logout/")
async def post_logout(member_number):
return JSONResponse({"member_number": member_number, "status": "OK"})Обратите внимание, если вы назовете экземпляр приложения другим именем, тогда и команда Uvicorn будет уже другой вид. Например, вы можете назвать приложение как perfect_router:
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from fastapi.responses import JSONResponse
perfect_router = FastAPI()
@perfect_router.get("/")
def path_root():
page = "<h1>Hello World!<h1>"
return HTMLResponse(content=page)
...В этом случае команда запуска веб-сервера приобретет следующий вид:
uvicorn main:perfect_router --host 127.0.0.1 --port 8000 --reloadПриложение FastAPI должно работать непрерывно, обрабатывая все поступающие запросы. Даже после перезагрузки системы.
Для этого мы задействуем диспетчер процессов systemd, который изначально есть в Linux. Тогда наше FastAPI-приложение станет фоновой службой.
Создадим специальный конфигурационный файл для systemd:
sudo nano /etc/systemd/system/fastapp.serviceЕго содержимое будет следующим:
[Unit]
Description=WebServer on FastAPI
After=network.target
[Service]
User=ИМЯ_ПОЛЬЗОВАТЕЛЯ
Group=ИМЯ_ГРУППЫ_ПОЛЬЗОВАТЕЛЕЙ
WorkingDirectory=/var/www/fastapp
ExecStart=/var/www/fastapp/venv/bin/uvicorn main:app --host 127.0.0.1 --port 8000
Restart=always
[Install]
WantedBy=multi-user.targetОбратите внимание, что нужно заменить:
-
ИМЯ_ПОЛЬЗОВАТЕЛЯна имя пользователя в вашей системе -
ИМЯ_ГРУППЫ_ПОЛЬЗОВАТЕЛЕЙна название основной группы пользователей, которым разрешен доступ. Если у вас нет группы, вы можете не указывать опцию «Group» совсем
ИМЯ_ПОЛЬЗОВАТЕЛЯ на имя пользователя в вашей системе
ИМЯ_ГРУППЫ_ПОЛЬЗОВАТЕЛЕЙ на название основной группы пользователей, которым разрешен доступ. Если у вас нет группы, вы можете не указывать опцию «Group» совсем
-
Запись
/var/www/fastapp— путь к приложению FastAPI -
Запись
/var/www/fastapp/venv— путь к виртуальной среде
Запись /var/www/fastapp — путь к приложению FastAPI
Запись /var/www/fastapp/venv — путь к виртуальной среде
Чтобы рабочий «демон» systemd задействовал новый конфигурационный файл, его нужно перезагрузить:
sudo systemctl daemon-reloadПосле этой команды systemd заново загрузить все конфигурационные файлы из директории /etc/systemd/system/, после чего они станут доступны для запуска и мониторинга.
Теперь запустим новую службу через имя, которое мы прописали в файле:
sudo systemctl start fastappОбратите внимание, что указанное в команде имя службы соответствует названию файла в директории systemd — fastapp.service.
Проверить статус запущенного приложения можно так:
sudo systemctl status fastappЧтобы включить автоматический запуск приложения при загрузке системы, можно выполнить команду:
sudo systemctl enable fastapp4. (Опционально) Использование Supervisor вместо Systemd
Supervisor — это система управления процессами для Unix-подобных операционных систем, в том числе и Linux. Он предназначен для мониторинга и управления запущенными приложениями.
По сути, Supervisor является более продвинутой альтернативой Systemd, однако он не встроен в систему по умолчанию.
-
Встроен в ОС. Нет необходимости в другой зависимости
-
Простой в использовании. Не требует обучения, поскольку им можно управлять как системным сервисом
Встроен в ОС. Нет необходимости в другой зависимости
Простой в использовании. Не требует обучения, поскольку им можно управлять как системным сервисом
-
Управлять процессами может любой пользователь. Необязательно быть суперпользователем
-
Имеет приятный веб-интерфейс для управления процессами
-
Работает на любом дистрибутиве
-
Больше гибкости в управлении процессами (объединение в группы, установка приоритетов)**
**
Управлять процессами может любой пользователь. Необязательно быть суперпользователем
Имеет приятный веб-интерфейс для управления процессами
Работает на любом дистрибутиве
Больше гибкости в управлении процессами (объединение в группы, установка приоритетов)**
**
Для установки утилиты в систему выполним стандартную команду:
sudo apt install supervisorПосле этого Supervisor будет работать в фоновом режиме и запускаться при каждом старте системы.
Тем не менее, лучше убедиться в том, что функция автозапуска включена. Мы явно воспользуемся стандартным Systemd для включения Supervisor:
sudo systemctl enable supervisorПосле чего вручную запустим его:
sudo systemctl start supervisorКонфигурация службы приложения
Как и в случае с Systemd, нам необходимо написать короткий конфигурационный файл, по которому Supervisor будет управлять нашим сервером Uvicorn.
Файл будет размещен в специальной директории Supervisor, предназначенной для файлов управляемых служб. Как и в случае с Systemd, назовем его fastapp:
sudo nano /etc/supervisor/conf.d/fastapp.conf
[program:fastapp]
command=/var/www/fastapp/venv/bin/uvicorn main:app --host 127.0.0.1 --port 8000
directory=/var/www/fastapp
user=ИМЯ_ПОЛЬЗОВАТЕЛЯ
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/www/fastapp/logs/fasterror.logРазберем написанную конфигурацию чуть подробнее:
-
command. Команда запуска приложения Uvicorn с указанием необходимых флагов и параметров. -
user. Имя пользователя в системе, из под которого будет производиться управление приложением. -
autostart. Автоматический запуск процесса. -
autorestart. Автоматический перезапуск процесса. -
redirect_stderr. Перенаправление вывода ошибок. -
stdout_logfile. Путь до файла, в который будет производиться вывод (в том числе и ошибки) запущенного процесса. Здесь мы указали рабочую директорию проекта, в которой появится отдельная папка под логи.
command. Команда запуска приложения Uvicorn с указанием необходимых флагов и параметров.
user. Имя пользователя в системе, из под которого будет производиться управление приложением.
autostart. Автоматический запуск процесса.
autorestart. Автоматический перезапуск процесса.
redirect_stderr. Перенаправление вывода ошибок.
stdout_logfile. Путь до файла, в который будет производиться вывод (в том числе и ошибки) запущенного процесса. Здесь мы указали рабочую директорию проекта, в которой появится отдельная папка под логи.
Так как мы указали в конфигурационном файле специальную директорию для хранения логов, нам необходимо ее явно создать:
sudo mkdir /var/www/fastapp/logs/****Запуск приложения через Supervisor
После добавления нового конфигурационного файла Supervisor должен спарсить его настройки также, как это выполнялось с Systemd. Для этого есть специальная команда:
sudo supervisorctl rereadПосле обновления конфигурации службу Supervisor нужно дополнительно перезапустить:
sudo supervisorctl updateПроверить статус запущенного (и управляемого) через Supervisor приложения можно с помощью отдельной команды с указанием имени службы, которая была указана в начале конфигурационного файла:
sudo supervisorctl status fastapp****Нужен сервер для практики? Арендуйте VPS/VDS в России — root-доступ, NVMe, DDoS-защита и поддержка 24/7.