Аватар

ramas

05 сентября 2024


Запуск FastAPI приложения вручную на Ubuntu сервере

nginx fastapi python uvicorn

Введение

Ранее это краткая заметка, сейчас неполноценный туториал. В ней мы развернем FastAPI приложение на сервере Ubuntu 24.04. Настроим проксирование через Nginx в WSGI сервер Gunicorn, который в свою очерез будет управлять воркерами Uvicorn.

Ранее Gunicorn использовали как менеджер для управления воркерами Uvicorn. Связано это с тем, что Uvicorn не поддерживал перезапуск мертвых рабочих процессов. Теперь эта проблема решена, и можно запускать Uvicorn напрямую, вместо Gunicorn.
uvicorn main:app --workers 3 --host 127.0.0.1 --port 8080

Что потребуется

  • Ubuntu сервер с белым IP-адресом. В моем случаи это арендованный в Beget виртуальный сервер Ubuntu 24.04 с адресом 31.128.38.212
  • Арендованный домен, с A-записью в DNS, указывающий на IP-адрес сервера. В качестве примера буду использовать свой домен ramzis.ru.

Подготовка сервера

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

apt update && apt upgrade

Проверим текущий часовой пояс установленный на сервере.

timedatectl

Если часовой пояс настроен неверно, выберем нужный из доступных и установим его (в моем случаи это Asia/Yekaterinburg):

timedatectl list-timezones
timedatectl set-timezone Asia/Yekaterinburg

Далее настроим брандмауэр. Перед его активацией добавим правило, разрешающее трафик для SSH:

ufw allow OpenSSH
ufw enable

Создадим нового пользователя с именем fast и добавим его в группу sudo, чтобы дать ему права суперпользователя.

adduser fast
usermod -aG sudo fast

Убедимся, что пользователь fast может выполнять команды с повышенными привилегиями. Переключимся на пользователя командой:

su - fast

Попробуем посмотреть содержимое директории /root, которое обычно доступно только для root. Введем следующую команду и подтверждим ввод паролем:

sudo ls -la /root

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

Рекомендации

  • Использовать аутентификацию на базе ключей SSH;
  • Отключить аутентификацию по паролю;
  • Запретить вход в систему под root;

FastAPI приложения

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

Создадим директорию для нашего проекта и перейдем в нее.

mkdir fastapi_project
cd fastapi_project

Затем создадим файл main.py

nano main.py

И запишем простое FastAPI приложение.

from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse

app = FastAPI()

@app.get('/', response_class=HTMLResponse)
async def hello(request: Request):
    return "<h1>Hello World</h1>"

Приложение мы будем изолировать с помоштю модуля venv. Установим необходимые пакеты и инструменты разработки.

sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools
sudo apt install python3-venv

Создадим виртуальную среду и активируем её.

python3 -m venv env
source env/bin/activate

После активации среды, установим зависимости и деактивируем ее.

pip install fastapi uvicorn gunicorn
deactivate

Установка и настройка Nginx

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

Установим Nginx.

sudo apt install nginx

Добавим правило и разрешим трафик для 80 порта.

sudo ufw allow 'Nginx HTTP'

conf.d или sites-available, sites-enabled

Далее создадим новый файл конфигурации для приложения.

sudo nano /etc/nginx/sites-available/fastapi_project

Запишем в него такой блок server. Не забываем заменить имя домена на свой.

server {
    listen 80;
    server_name ramzis.ru;

    location / {
        include proxy_params;
        proxy_pass http://127.0.0.1:8080;
    }
}

Сохраним и добавим символическую ссылку на конфиг.

sudo ln -s /etc/nginx/sites-available/fastapi_project /etc/nginx/sites-enabled

Перезапустим Nginx, чтобы считать новую конфигурацию.

sudo systemctl restart nginx

На этом этапе вы может проверить работу приложения, так скажем, удостоверится что все работает. Для этого активируйте вертуальную среду, и запустите приложение.

source env/bin/activate
gunicorn main:app --workers 3 --worker-class uvicorn.workers.UvicornWorker --bind 127.0.0.1:8080

Откроете браузер и введете в адресную строку имя вашего домена.

Проверка работы приложения

Создание службы

Автоматизируем запуск приложения.

Создадим юнит.

sudo nano /etc/systemd/system/fastapi_project.service

Запишем правила и команды.

[Unit]
Description=FastAPI project
After=network.target

[Service]
User=fast
WorkingDirectory=/home/fast/fastapi_project
Environment="PATH=/home/fast/fastapi_project/env/bin"
ExecStart=/home/fast/fastapi_project/env/bin/gunicorn main:app --workers 3 --worker-class uvicorn.workers.UvicornWorker --bind 127.0.0.1:8080

[Install]
WantedBy=multi-user.target

Активируем и добавлим в автозагрузку.

sudo systemctl enable --now fastapi_project

Приложение запущено. Даже если перезагрузить сервер, служба автоматически запустится и восстановит его работу.

Протокол HTTPS

Получим бесплатный сертификат от центра сертификации Let's Encrypt. Для этого установим пакет Certbot с плагином Nginx.

sudo apt install python3-certbot-nginx

Разрешим трафик для 443 порта.

sudo ufw allow 'Nginx HTTPS'

Запустим Certbot с плагином и укажем для какого домена получить сертификат.

sudo certbot --nginx -d ramzis.ru

Будет предложено ввести адрес электронной почты и согласиться с условиями использования. После этого в ранее созданный конфигурационный файл Nginx будут внесены изменения, и сайт станет доступен по протоколу HTTPS.