Документация LMS версия 0.1.0

Документация/Начало/Установка

Написано наполовину

Установка

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

Главное правило: чек-лист ниже проходится до установки. Каждый его пункт стоит десяти минут, а найденный после установки — нескольких часов.

Что нужно от сервера #

Минимум Комфортно
Ядра 2 4
Память 4 ГБ 8 ГБ
Свободный диск 20 ГБ 40 ГБ
ОС Ubuntu 22.04 / 24.04, Debian 12
Docker 24+ с плагином compose v2 29+

Память — про сборку, а не про работу. Работающая установка укладывается примерно в 1,5 ГБ. Сборка образа съедает 2–3 ГБ разом: если на сервере уже что-то живёт, сборка на нём — самый быстрый способ уронить соседей.

Чек-лист до установки #

1. Время синхронизировано #

timedatectl

Нужно System clock synchronized: yes. Это не формальность: одноразовые коды двухфакторной защиты ломаются при расхождении больше 30 секунд — владелец не сможет войти в собственную админку. Плюс от часов сервера считаются сроки доступа и отложенные события, а Let's Encrypt не выпустит сертификат при заметном расхождении.

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

mkdir -p /etc/systemd/timesyncd.conf.d
printf '[Time]\nNTP=time.cloudflare.com\n' > /etc/systemd/timesyncd.conf.d/10-reachable-ntp.conf
systemctl restart systemd-timesyncd
timedatectl timesync-status

Часовой пояс сервера при этом значения не имеет: приложение работает в UTC и показывает даты в поясе школы. Обязательна именно синхронность.

2. Место и память #

df -h /
free -h

20 ГБ свободных. И решите здесь же, собирается образ на этом сервере (нужно ещё 3 ГБ памяти) или переносится готовым с другой машины.

3. Порты #

ss -ltnp | grep -E ':(80|443|5432|6379|3000)\b'
  • 80 и 443 нужны, если установка ставит свой прокси. Заняты чужим прокси — это отдельный сценарий, см. ниже.
  • 5432 и 6379 наружу не нужны вообще: PostgreSQL и Redis живут во внутренней сети Docker и портов на хост не публикуют. Если 5432 занят чужой базой — это нам не мешает.

4. Домен #

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

getent hosts school.example.com
curl -s https://ifconfig.me

Два адреса должны совпасть. Домен за проксирующим DNS или CDN — выпуск сертификата пойдёт иначе, и это надо решить заранее, а не в момент установки.

5. Исходящая связь #

curl -s -o /dev/null -w '%{http_code}\n' https://api.resend.com
timeout 6 bash -c '</dev/tcp/smtp.yandex.ru/587' && echo "587 открыт" || echo "587 закрыт"

Закрытый исходящий SMTP — норма, а не поломка. У многих хостеров порты 25, 465, 587 и 2525 закрыты по умолчанию и открываются по заявке. На сервере первой установки закрыты были все четыре, до всех проверенных провайдеров, при работающем исходящем HTTPS. Если письма нужны — либо открывайте порт заявкой хостеру, либо берите провайдера, который принимает письма по HTTPS.

6. Откуда ставится #

Из чистого клона репозитория, а не из папки, где кто-то пишет код. Рабочая копия содержит свой .env, свои node_modules и незакоммиченные правки: установка перепишет первое и споткнётся о третьем. Проверено дорогой ценой на первой же установке.

Установка за уже работающим прокси #

Отдельный сценарий, и он не автоматизирован. Если 80 и 443 уже занял чужой Traefik, Nginx или Caddy, автоматический установщик неприменим: он рассчитывает, что порты его. Порядок в этом случае ручной — коробка поднимается без своего прокси, а маршрут к ней добавляется в уже стоящий.

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

Первая проверка #

Убедиться, что встало верно, можно не заводя ни одного ученика:

  • страница входа открывается по вашему домену, сертификат настоящий;
  • http:// отдаёт перенаправление на https://, а не страницу;
  • владелец вошёл и настроил двухфакторную защиту сам — см. предупреждение ниже;
  • в админке видно состояние очередей и фоновых задач;
  • создался тестовый курс с одним уроком, и урок открывается.

Предупреждение, которое дороже остальных #

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

Практически это значит: первый вход делает тот, кто останется владельцем школы, а не подрядчик, который ставит. Школа, у которой уволился техспециалист, настроивший двухфакторку на себя, останется без доступа к собственной админке.

Это находка первой установки, она известна и чинится. Пока не починена — порядок входа решает всё.

Обновление #

Раздел не написан, и это не забывчивость.

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

Что известно точно уже сейчас:

  • обновление — ваше событие, а не наше: оно не приходит само;
  • миграции базы генерируются, а не пишутся руками, и применяются отдельным шагом;
  • перед обновлением снимается резервная копия, и её восстановимость надо проверить, а не предположить.

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

Эта страница в Markdown