Найти тему
Maxim

Поднимаем свой сервер на Ubuntu с Nginx и Python

Пишешь свою игру с поддержкой сети? Планируешь свой сайт или веб-сервис? Бот для телеграмма или навык Яндекс Алисы?

Всему этому нужен backend. А backend'у нужна инфраструктура.

Поднимаем свой сервер со своим доменом в интернете на Ubuntu Linux, настраиваем стек Nginx + Gunicorn + Flask, защищаем все соединения при помощи SSL.

Часть первая.

Дисклеймер (Disclaimer)

Это не универсальный метод настройки веб серверов, а всего лишь частное представление того, как это делаю я для своих проектов. Как говорил один кулинар, когда собирался готовить то ли борщ, то ли шурпу:

Знатоков того самого единственного правильного рецепта я попрошу сегодня не беспокоится.

Я не сторонник простых инструкций написанных по принципу - "скопируйте сюда этот файл, а сюда перепишите эту команду и нажмите ввод", однако и превращать эту статью в полный курс по всем аспектам затронутым в данном руководстве нет никакой возможности. Поэтому это будет некий средний вариант, где я буду показывать вам последовательность действий, попутно поясняя смысл введены команд, их ключей и параметров конфигурационных файлов.

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

Задача

Нам необходимо настроить и запустить веб-сервер, на котором будет работать на проект написанный на языке Python.

Какой проект? Да какой угодно. Веб сайт, чат бот для Telegram или навык для Яндекс Алисы или Google Assitant`а, возможно сервис который ведет статистику пользователей вашей игры, либо даже просто статичная веб страничка, вот, например, с этой инструкцией.

Где.

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

Регистрация доменного имени. Я для этой цели воспользовался сервисом регистрации от AWS - Route 53. Просто потому, что я давно им пользуюсь, и это не первый домен который я у них регистрирую, вы же, повторюсь, можете воспользоваться услугами абсолютно любого регистратора.

Да, возможно кто то скажет - ну зачем я буду тратить лишние 10-20 долларов на доменное имя, если можно ходить на сервер просто по IP? И да, и нет. Современные правила работы предполагают использование зашифрованного соединения с нашим сервером, а сервисы предоставляющие сертификаты требуют именно зарегистрированное доменное имя, а не IP адрес. Без использования шифрования пользователь, в лучшем случае будет получать постоянные сообщения браузера об угрозе безопасности, а в худшем вообще не сможет подключится.

Итак, я только зарегистрировал имя blueoctopus.cc, и на текущий момент на нем ни одной записи.

Саму виртуальную машину мы сделаем в Yandex Cloud.

Ключи доступа.

Даже если это покажется странным, но начнем мы не с виртуальной, а с вашей домашней машины. Поскольку метод аутентификации на сервере предполагает использование пары ключей SSH (Secure SHell), то мы их сразу ее и создадим, что бы при создании виртуальной машины передать серверу открытую часть.

Итак, откроем консоль кликнув на соответствующую иконку, либо нажав комбинацию клавиш Ctrl + Alt + T (Command (⌘) + T) и перейдем в каталог назначенный по умолчанию для хранения ключей.

cd .ssh

Если такой папки нет, то ее необходимо создать

mkdir .ssh

Ключи удобнее хранить в специально обозначенном каталоге, тогда не прийдется каждый раз при подключении указывать параметр с его размещением.

Если при попытке выполнить указанные выше действия вы столкнулись с ошибками, то вероятно вы используете ОС Wndows на своем ПК. Насколько мне известно, на Windows 10 c 2018 позволяет использовать SSH, только его необходимо отдельно установить. Официальный сайт Microsoft говорит, что:

OpenSSH можно использовать для подключения устройств с Windows 10 (версия 1809 и более поздние) Чтобы установить компоненты OpenSSH, сделайте следующее:
Откройте приложение Параметры, выберите элементы Приложения > Приложения и возможности, щелкните Дополнительные возможности.
Просмотрите этот список и определите, установлено ли средство OpenSSH. Если нет, выберите пункт Добавить компонент в верхней части страницы и сделайте следующее:
Найдите Клиент OpenSSH и щелкните Установить.

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

Продолжим. Напомню, у нас открыт терминал и мы находимся в папке .ssh

Напечатаем простую команду:

ssh-keygen

Генератор предложит вам указать уникальное название ключа, защитить его дополнительно паролем, и вроде бы будет еще пара вопросов, которые никто не читает.

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

В итоге у вас будет два файла: server_key - это ваш приватный ключ, его необходимо оставить в папке .ssh вашей домашней директории, и никому никогда не передавать. И server_key.pub - это, соответственно, публичная часть, содержимое которого необходимо загрузить при создании конфигурации нашей виртуальной машины.

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

cat server_key.pub

Для удобства, большой точности и безопасности копирования в буфер можно воспользоваться утилитами xclip для Linux и pbcopy для MacOS.

Виртуальная машина в Yandex Cloud

Теперь откроем консоль Yandex Cloud. Если у вас нет аккаунта, то его придется создать, думаю, что с регистрацией на Яндекс проблем возникнуть не должно.

Далее в меню слева выбираем раздел Compute Cloud и нажимаем кнопку Создать ВМ. Я специально решил делать этот пример на сервисах яндекса, поскольку у них есть подробное описание каждого пункта меню на русском языке.

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

Давайте быстро пройдемся по пунктам:

Имя и описание - все понятно, уникальное название и некоторые подробности, что бы вы сами не забыли что это за виртуалка крутится у вас в облаке.

Зона доступности - мне яндекс предложил ru-central-b, так и оставлю.

Операционная система - Ubuntu 20.04

Диск - HDD на 13 Gb

Платформа - Intel Ice Lake

vCPU - 2 (Количество ядер процессора, наверное хватило бы и одного, но яндекс так уже не предлагает)

Гарантированная доля vCPU - 20% (Минимальная гарантированная доля производительности. По моему опыту, при настройке загрузка ЦП не превышает 1-2%, так что этой доли нам более чем достаточно не только для настройки сервера, но и для небольших сервисов развёрнутых на нем.)

RAM - Очевидно оперативная память. Выбирайте минимум 2 GB

Прерываемая - самый спорный пункт. Его выбор делает большую скидку на ВМ, однако это дает право яндексу остановить ее в любой момент. Сервер будет остановлен корректно, так что за сохранность данных переживать не стоит, но включать его обратно прийдется "вручную". Для этого урока я этот пункт включу, но если настраиваемый вами сервер планируется в дальнейшем использовать в рабочем режиме, то выбирать этот пункт точно не стоит.

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

Думаю здесь необходимо небольшое пояснение - в автоматическом режиме яндекс, конечно, предоставит публичный адрес, но проблема в том что при каждом перезапуске сервера он будет новым, что неприемлемо для настройки доменного имени. И да, это стоит отдельных денег, это нормально. Постоянно зарезервированный адрес стоит немного дороже, чем автоматический, и еще дороже будет стоить зарезервированный, но неиспользуемый адрес. (На момент написания этой статьи это около 150 рублей в месяц.)

В любом случае, когда вы выберите пункт "список", то скорее всего получите сообщение о том, что в вашем облаке нет свободных статических IP-адресов. В конце этого сообщения будет ссылка с названием "список адресов", смело нажимаем на нее и попадаем в раздел Virtual Private Cloud.

Выбираем в меню слева пункт "IP-адреса", и потом жмем на кнопку "Зарезервировать адрес", тут главное проследить что бы зона доступности, где резервируется адрес была той же, где создаётся сервер. Если все правильно - нажимаем "Зарезервировать" и возвращаемся к конфигурированию нашей ВМ.

Теперь при настройке публичного адреса в пункте список будет доступен наш зарезервированный IP. Выберем его и перейдём к настройке доступа.

Сервисный аккаунт - нужен если вы планируете получать доступ с виртуальной машины к другим ресурсам облака. (Например к серверу базы данных). В данном случае в нем нет необходимости.

Логин - имя пользователя в на сервере. Тут все просто, главное не выбирайте root или www-data. Я укажу просто max.

SSH-ключ - содержимое того самого server_key.pub, которое мы скопировали в буфер обмена. Просто вставьте его сюда.

Доступ к серийной консоли не включаем. Считайте это аварийным режимом, при штатной работе сервера он должен быть отключён.

Ну вот, теперь внимательно смотрим на правую колонку, и если цена нас устраивает - жмем на кнопку Создать ВМ внизу страницы.

Подключение к серверу

Наша виртуальна машина готова. Поскольку мы еще не строили доменное имя, то давайте подключимся по IP

ssh max@178.154.219.150

Тут все просто: login@ip-adress

Login - Логин, который мы указали при конфигурации.

ip-adress - Зарезервированный за ВМ статический адрес.

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

The authenticity of host 'example.com (178.154.219.150)' can't be established.
ECDSA key fingerprint is SHA256:7Q4nIqjuo/lSXWFkt9RaJYVHrT6LUAc6KWrdQ4/DDeA.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

Все в порядке, так и должно быть, это сервер присылает отпечаток ключа для проверки. Просто напечатаем yes и нажмем enter еще раз.

Все, теперь мы видим приглашение командной строки нашей виртуальной машины.

Установка утилит

Давайте для начала обновим данные о репозиториях:

sudo apt update

И, при необходимости, обновим сами пакеты:

sudo apt upgrade

Жмем (Y)es и немного подождем.

Кстати, пока идет обновление, обращу ваше внимание, что мы использовали sudo, для временного повышения полномочий, но пароль запрошен не был. Это странная особенность ВМ, и если вас это беспокоит - напишите, расскажу как это исправить.

Меня данная ситуация вполне устраивает, поэтому продолжаем. Большинство сервисов поставляют ВМ со схожим набором консольных утилит, но я предпочитаю все же выполнить установку одной строкой все требуемых мне, а не проверять их наличие по отдельности. Если что то из этого уже установлено - установщик просто пропустит этот шаг.

sudo apt install mc git curl wget rsync zip unzip

Опять же жмем (Y)es и немного подождем.

И что бы не терять время пройдемся по утилитам:

mc - Midnight Commander, консольный двух-панельный файловый менеджер. Большинство операций, я выполняю через него.

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

curl - Мне кажется не существует сетевого протокола, по которому эта утилита не могла бы послать запрос прямо из командной строки.

wget - качает файлы по ссылке. Можно конечно качать и с помощью curl, но эта мне как то привычнее.

rsync - удобная синхронизация файлов и каталогов, можно запускать по расписанию для создания резервных копий.

zip и unzip - очевидно архиваторы zip. Родные архиваторы bzip2 и gzip как правило есть всегда, а эти бывает, что и не установлены на старте.

Сервер SSH

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

Для этого откроем файл с настройками параметров.

Это можно сделать напечатав в командной строке:

sudo nano /etc/ssh/sshd_config

Либо запустив midnight commander, найти, выделить файл и нажать F4. При первом запуске МС попросить выбрать предпочитаемый редактор, рекомендую выбрать nano

sudo mc

И да, большую часть команд и правок мы будем вносить используя sudo, (Substitute User and do, дословно «подменить пользователя и выполнить»). Это необходимо для повышения наших полномочий до уровня root

Давайте взглянем на файл конфигурации. Большинство строк с параметрами комментированы символом #, предполагается, что значения указанные в них - будут использованы по умолчанию. Опираясь на один из принципов программирования "явное лучше чем неявное" - пройдемся по параметрам, которые я считаю важным указать явным способом.

Пройдемся по файлу сверху вниз, и первый параметр который нам нужен выглядит так:

PermitRootLogin prohibit-password

Очевидно из названия - разрешить руту подключатся удалённо с использованием непарольных методов аутентификации. Например сканер отпечатка, смарт-карта и т.д.

Раскомментируем строку и ставим значение в no:

PermitRootLogin No

Никаких удалённых авторизаций и входов для root

Следующий параметр отвечает за возможность авторизации по SSH ключу. Мы именно таким способом и зашли на наш сервер.

PubkeyAuthentication yes

Укажем это явно, оставляем yes по умолчанию, просто удалим знак комментария.

Дальше будет длинная строка с параметрами отделёнными табуляцией:

AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2

Это указание на то где искать файл с публичными частями ключей для авторизации пользователей. Оставляем как есть, просто раскомментируем.

И последний обязательный пункт:

PasswordAuthentication yes

Удаляем символ комментария и устанавливаем параметр в no. Никаких парольных идентификаций, только файлы ключей.

PasswordAuthentication no

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

X11Forwarding yes

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

Все. Теперь нажимаем Ctrl + X и подтверждаем запись файла.

Если вы использовали midnight commander то нажмите Ctrl + O, это скроет панели, отобразив терминал, но не закроет сам MC, так же как и не прервет сессию sudo. Повторное нажатие вернет панели обратно.

Перезапустим наш сервис SSH, что бы применить внесенные изменения.

sudo systemctl restart ssh

Можно отключится напечатав exit, и подключится опять, для проверки работоспособности, но это необязательно.

Есть что дополнить?

https://github.com/trash-max/howto

#server #ubuntu #Nginx #gunicorn #flask