Деплоим Wagtail на VPS

May 19, 2020

Описанный ниже способ размещения подходит для любых проектов на Django, Wagtail — частный случай.

Потребуется:

ОС и его версия большой роли не играют. Важно, чтобы была возможность установить нужные пакеты и версии. Желательно всё самое свежее.

Надо оговориться, что мой проект называется просто blog, следовательно, джанговское приложение, в котором сам блог реализован, у меня называется иначе — blogapp. Учитывайте, что каждый раз, когда в коде или команде встречается blog, имеется в виду джанговский проект, а не приложение.

Установка ПО и подготовка сервера

Сперва обновим сервер:

apt update && apt upgrade

Устанавливаем необходимые пакеты и дополнительные для удобвства работы на сервере:

apt install nginx postgresql python3-dev python3-venv gcc git supervisor vim tree htop zip unzip 

Создадим пользователя без прав и войдём от его имени:

adduser --disabled-login wagtailblog
su - wagtailblog

У меня код хранится в репозитории Github, поэтому просто клонирую его. Также можно загрузить файлы через scp с компьютера.

git clone https://github.com/user/repo.git

Устанавливаем виртуальное окружение Python с необходимыми модулями:

python3 -m venv env
source env/bin/activate
pip install wagtail wagtail-markdown pygments psycopg2
cd blog/
pip install -r requirements.txt

psycopg2 это пакет, который обеспечит нам коннект сайта к базе данных PosgreSQL. Если он не установился обычным способом (произошла ошибка компиляции при установке через pip install psycopg2), то можно установить бинарник:

pip install psycopg2-binary

Покидаем юзера wagtailblog командой exit.

Создание и настройка базы данных

Создадим БД wagtailblog.

sudo su - postgres
createdb wagtailblog
psql wagtailblog

Мы оказались в консоли PostgreSQL. Выполним:

CREATE ROLE wagtailblog WITH PASSWORD 'password';
GRANT ALL PRIVILEGES ON DATABASE wagtailblog TO wagtailblog;

Мы добавили пользователя базы данных с именем wagtailblog и дали ему все привелегии на БД wagtailblog. Закроем шэлл \q+Enter.

Теперь войдём под юзером postgres на сервер БД:

psql -U postgres

Разрешим логиниться wagtailblog в базу данных:

ALTER ROLE "wagtailblog" WITH LOGIN;
\q

Выходим из под юзера postgres.

Подключение БД

Теперь надо подключить базу данных к сайту в blog/settings/base.py.

Сначала закомментируем или удалим подключение к БД SQLite, которая создаётся по-умолчанию:

# # SQLite (simplest install)
# DATABASES = {
#     'default': {
#         'ENGINE': 'django.db.backends.sqlite3',
#         'NAME': join(PROJECT_ROOT, 'db.sqlite3'),
#     }
# }

Подключим нашу базу данных:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'wagtailblog',
        'USER': 'wagtailblog',
        'PASSWORD': 'password',
        'HOST': 'localhost',  # Set to empty string for localhost.
        'PORT': '',  # Set to empty string for default.
        'CONN_MAX_AGE': 600,  # number of seconds database connections should persist for
    }
}

Выполняем миграции и создаём аккаунт администратора:

./manage.py makemigrations
./manage.py migrate
./manage.py createsuperuser

Можно проверять сайт. Запускаем сервер через manage.py:

./manage.py runserver 0.0.0.0:8000

Переходим в браузере по адресу http://{IP сервера}:8000/ Сайт должен работать.

Настройка веб-сервера.

Девелопмент сервер manage.py не подходит для постоянной работы блога.

Нам нужен WSGI-сервер как интерфейс между Wagtail и Nginx. Я выбрал uWSGI. Можно взять другой. Например, gunicorn.

Принцип работы такой: uWSGI работает на 8080 порту (или любом другом свободном), а Nginx проксирует запросы с 80 порта на 8080.

uWSGI будет работать из виртуального окружения и запускаться shell-скриптом. За его выполнением будет следить Supervisor.

uWSGI

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

pip install uwsgi

Создаём файл runuwsgi.sh в домашней папке пользователя wagtailblog с содержимым:

#!/bin/bash
source /home/wagtailblog/env/bin/activate
uwsgi --http :8080 --home /home/wagtailblog/env --chdir /home/wagtailblog/blog -w blog.wsgi --logger file:logfile=/tmp/uwsgi.log,maxsize=2000000

Опишу параметры uWSGI подробней:

--http :8080 # Задаём номер порта, на котором будет работать сервер
--home /home/wagtailblog/env # Путь до папки виртуального окружения
--chdir /home/wagtailblog/blog # Путь до корневой папки проекта
-w blog.wsgi # Указываем wsgi-модуль проекта
--logger file:logfile=/tmp/uwsgi.log,maxsize=2000000 # Лог веб-сервера

Скрипту нужно дать права на исполнение:

chmod +x runuwsgi.sh

runuwsgi.sh активирует виртуальное окружение и запускает uWSGI с параметрами. Все эти параметры можно вынести в конфигурационный файл .ini. Описание есть в доках. Также настройка uWSGI с использованием конфига освещается на Хабре.

Nginx

Нужно настроить виртуальный хост Nginx. Для этого создаём файл в папке /etc/nginx/sites-available/. Мой конфиг выглядит следующим образом:

server {
    listen 80;

    server_name blog.rmrf.space;

    location / {
            proxy_pass http://127.0.0.1:8080;
            proxy_set_header X-Forwarded-Host $server_name;
            proxy_set_header X-Real-IP $remote_addr;
            add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
    }
}

В location / задаются правила проксирования.

Для активации конфига создадим симлинк в папку /etc/nginx/sites-enabled:

ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/

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

nginx -t

Для применения настроек требуется перезагрузка Nginx:

nginx -s reload

На данный момент можно проверить как это всё работает:

  1. Переходим в браузере на IP сервера. По-умолчанию открывается 80 порт. На нём работает Nginx. Если в этот момент uWSGI не работает, то получим ошибку 502.
  2. Запустим скрипт runuwsgi.sh вручную. Сайт должен подняться.

Supervisor

Пора настроить Supervisor для автоматического запуска скрипта. Создаём конфиг /etc/supervisor/conf.d/wagtailblog.conf:

[program:uwsgi]
command=/home/wagtailblog/runuwsgi.sh
user=wagtailblog
process_name=%(program_name)s
numprocs=1
autostart=true
autorestart=true
redirect_stderr=true

Перезапустим Supervisor:

service supervisor restart

Он будет запускать uWSGI от имени пользователя wagtailblog, перезапускать его в случае падения и перенаправлять STDERR в лог /var/log/supervisor/*.log.

SSL-сертификат

Для того, чтобы сайт работал по защищённому протоколу нам нужен сертификат. Установим бесплатный от Let'sEncrypt.

apt install certbot
certbot certonly --standalone

certbot сгенерирует файлы сертификата fullchain.pem и privkey.pem. Для установки добавим в конфиг Nginx следующее:

    #Nginx начнёт случать 443 порт
    listen 443 ssl;

    #Сертификат
    ssl_certificate /etc/letsencrypt/live/mysite/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mysite/privkey.pem;

    #Переадресация на HTTPS
    if ($scheme != "https") {
               return 301 https://$host$request_uri;
    }

Готово.

Ссылки

^