Настройка web–сервера для приложений на Python

27.03.2023

В статье содержится руководство по первичной настройке инфраструктуры сервера для хостинга web–сайтов на основе Debian 11, разработанных с использованием Python.
Получаемое окружение предназначено для использования в процессе разработки, но, с некоторыми оговорками, может использоваться и в production–режиме.

Предполагается, что:

  1. сайт, размещаемый на сервере имеет название mysite.com;
  2. команды начинающиеся с символа # выполняются с root–правами;
  3. читатель обладает базовыми знаниями о Linux и предназначении используемого ПО, а также может самостоятельно восполнить пробелы из документации; в связи с этим в тексте опущены пояснения "очевидных" моментов.

Обновление дистрибутива, локаль и пользователь

При первом подключении к серверу необходимо.

  1. Обновить пакеты дистрибутива:
# apt-get update; apt-get upgrade
  1. Добавить русскоязычную локаль:
# dpkg-reconfigure locales

В появившемся окне выбора локалей и их кодировок нужно выбрать en-us.UTF-8 и ru_RU.UTF-8. По умолчанию ставим en-us.UTF-8.

  1. Перезагрузить сервер:
# reboot
  1. Добавить пользователя admin, от имени которого будут запускаться приложения:
# adduser admin

ssh

Для доступа по ssh будет использоваться сертификат, поэтому если его нет, нужно предварительно его создать.

После получения сертификата в /home/admin:

mkdir .ssh
cd .ssh
nano authorized_keys

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

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCv5rWbJVspLpviY4...9ILXJOxIKpHH0luUiTQcVaRqyTYt1 p.menshih@gmail.com

Далее редактируем конфигурационный файл демона ssh:

# nano /etc/ssh/sshd_config

Минимальное содержимое конфига:

AuthorizedKeysFile                      .ssh/authorized_keys
ChallengeResponseAuthentication         no
ClientAliveCountMax                     10000
ClientAliveInterval                     60
PasswordAuthentication                  no
PermitRootLogin                         no
PubkeyAuthentication                    yes
Subsystem                               sftp /usr/lib/openssh/sftp-server
TCPKeepAlive                            yes
UsePAM                                  yes

Перезапускаем демон:

# systemctl restart ssh

Если все сделано правильно и ssh–клиент настроен корректно, можно отключиться от сервера и переподключиться с использованием сертификата.

Смена имени хоста

Ясно определенное имя хоста (например, mysite.com) отображается в приглашении консоли и, когда консолей много, снижает риск выполнения каких-либо команд не на той машине.

Для изменения имени необходимо отредактировать файл hostname:

# nano /etc/hostname

В открывшемся редакторе пишем новое имя хоста.

После перезагрузки сервера в приглашении консоли появится новое имя.

TLS сертификат

Для получения валидного TLS–сертификата можно воспользоваться утилитой Certbot от сервиса Let's Encrypt.

Документация по установке находится на официальном сайте.

Для корректной работы сайта необходимо получить сертификат на домен mysite.com:

certbot certonly --standalone -d mysite.com

nginx

Документация по установке находится на официальном сайте.

После установки нужно удалить конфигурационный файл по умолчанию и создать конфигурационный файл сайта /etc/nginx/conf.d/mysite.com.conf:

# cd /etc/nginx/conf.d
# rm -rf default.conf
# nano mysite.com.conf

Содержимое mysite.com.conf:

# Обработка 80-го порта для домена mysite.com.
server {
    listen 80;
    server_name mysite.com;

    return 301 https://mysite.com$request_uri;
}

# 443 порт для mysite.com.
server {
    listen 443 ssl http2;
    server_name mysite.com;

    # Пути к используемым сертификатам.
    ssl_certificate /etc/letsencrypt/live/mysite.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mysite.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/mysite.com/fullchain.pem;

    # Логирование запросов.
    access_log  /var/log/nginx/mysite.com_access.log combined;
    error_log   /var/log/nginx/mysite.com_error.log error;

    # Проксирование всех запросов на локальный порт 8000.
    location / {
        proxy_http_version 1.1;
        proxy_pass http://127.0.0.1:8000;
    }
}

Обратите внимание, что описанная конфигурация:

  1. предполагает использование сайта только по SSL;
  2. Для проксирования запросов от сайта используется порт 8000, который будет указан позже в конфигурации gunicorn.

После проверки конфигурационного файла с помощью команды:

# nginx -t

сервер необходимо запустить командой:

# systemctl start nginx

Python

Для установки и управления нужными версиями Python используется pyenv.

Документация по установке находится на официальном сайте. В случае с сервером рекомендуется установить pyenv с помощью pyenv-installer для пользователя admin.

После установки pyenv необходимо обновить переменные окружения для используемого терминала и установить зависимости для сборки Python.

После установки зависимостей нужную версию Python можно установить командой:

pyenv install X.Y

где X.Y — версия Python, например 3.11.

Напоследок нужную версию Python нужно сделать глобальной:

pyenv global X.Y

Служба systemd для gunicorn

Gunicorn — WSGI HTTP–сервер для запуска приложений, созданных на Python. Используется в качестве прослойка между nginx и приложением cайта.

Прежде всего необходимо установить gunicorn. Сделать это можно в виртуальном окружении вашего проекта:

(venv) $ pip install gunicorn

Далее создаем директории и файл службы для systemd:

mkdir -p ~/.config/systemd/user
nano ~/.config/systemd/user/gunicorn.service

Содержимое ~/.config/systemd/user/gunicorn.service (предполагается, что приложение сайта находится в папке /home/admin/mysite.com):

[Unit]
After=network.target
Description=gunicorn daemon

[Service]
WorkingDirectory=/home/admin/mysite.com/
ExecStart=/home/admin/venv/bin/gunicorn -b 127.0.0.1:8000 mysite.wsgi:application
Restart=always

[Install]
WantedBy=multi-user.target

Активация службы:

systemctl --user enable gunicorn.service

Запуск службы:

systemctl --user start gunicorn.service

Важно!
Systemd останавливает все службы пользователя после закрытия последней сессии.
Таким образом после закрытия всех соединений с сервером gunicorn перестанет работать.
Чтобы подобного не происходило, нужно выполнить следующую команду от имени root:

# loginctl enable-linger admin

PostgreSQL

Руководство по установке на официальном сайте.