Files
LMS/deploy/DEPLOY.md

7.9 KiB
Raw Blame History

Деплой LMS на сервер lms.our-place.ru

Стек целиком запускается в Docker. Java на сервере не устанавливается — приложение собирается и работает внутри контейнеров (multi-stage Dockerfile: сборка на JDK 21, запуск на JRE 21).

Компоненты:

Сервис Контейнер Наружу
web (Thymeleaf UI) lms-web 127.0.0.1:8090 (проксирует nginx)
gateway lms-gateway нет
identity / academic / progress lms-* нет
PostgreSQL 18 lms-postgres нет

Данные лежат в именованных volume: lms_pgdata (БД), lms_submissions (решения), lms_assets (картинки материалов).


0. Что нужно

  • Сервер с Ubuntu 22.04/24.04 (или другим Linux с Docker), sudo/root.
  • Домен lms.our-place.ru, A-запись которого указывает на IP сервера.
  • Открытые порты 80 и 443 (443 — если настраиваете HTTPS).

1. Установка Docker

curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker "$USER"   # перелогиньтесь, чтобы работать без sudo
docker compose version            # нужна версия v2

2. Получить код

sudo mkdir -p /opt/lms && sudo chown "$USER" /opt/lms
git clone <URL-репозитория> /opt/lms
cd /opt/lms

3. Настроить окружение

cp .env.prod.example .env.prod
nano .env.prod

Обязательно задайте LMS_DB_PASSWORD и LMS_INTERNAL_TOKEN. Остальные значения по умолчанию подходят.

LMS_INTERNAL_TOKEN — общий секрет для внутренних вызовов identity из academic/progress (профиль студента, состав группы). Сгенерируйте длинную случайную строку (например, openssl rand -hex 32) и укажите её в .env.prod. Compose передаёт одно и то же значение identity, academic и progress. Значение по умолчанию dev-internal-token для production не используйте; .env.prod не коммитьте.

4. Собрать и запустить

./deploy/deploy.sh up

Скрипт соберёт образы (первый раз ~5–15 минут: скачиваются Gradle и зависимости) и поднимет контейнеры. Проверка:

docker compose -f docker-compose.prod.yml --env-file .env.prod ps
curl -fsS http://127.0.0.1:8090/actuator/health   # {"status":"UP",...}

5. Nginx + HTTPS

sudo apt-get update && sudo apt-get install -y nginx certbot python3-certbot-nginx
sudo mkdir -p /var/www/certbot

sudo cp deploy/nginx/lms.our-place.ru.conf /etc/nginx/sites-available/lms.our-place.ru.conf
sudo ln -sf /etc/nginx/sites-available/lms.our-place.ru.conf /etc/nginx/sites-enabled/lms.our-place.ru.conf
sudo rm -f /etc/nginx/sites-enabled/default

sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d lms.our-place.ru --redirect -m admin@our-place.ru --agree-tos

certbot --nginx сам добавит TLS-блок и редирект с HTTP на HTTPS. Автопродление уже настроено пакетом (systemctl status certbot.timer).

6. Первый запуск приложения

Откройте https://lms.our-place.ru → откроется /setup → создайте администратора.

6a. Наполнение данными

Дальше всё через интерфейс: импорт групп (.xls), импорт лабораторной ZIP'ом, раздача вариантов, оценки и защита, материалы. Подробный порядок с проверками — в IMPORT.md. Файлы со списками студентов и выгрузками паролей — персональные данные, держите их вне репозитория.

7. Обновление версии

cd /opt/lms
git pull
./deploy/deploy.sh up        # backup → сборка → миграции → перезапуск

deploy.sh up обязательно делает backup перед обновлением. Если backup завершился ошибкой, деплой прерывается. Миграции БД (Flyway) применяются автоматически при старте сервисов.

8. Резервное копирование

Полная инструкция — BACKUP.md. Кратко:

./deploy/backup.sh backup          # БД + решения + материалы
./deploy/backup.sh list
./deploy/backup.sh verify <dir>
./deploy/backup.sh restore <dir>   # destructive, требует ввода RESTORE

Backup включает pg_dump БД, volume решений и volume материалов, контрольные суммы и manifest. По умолчанию хранится 14 дней (LMS_BACKUP_KEEP_DAYS), каталог — /opt/lms/backups (LMS_BACKUP_DIR).

Ежедневное расписание:

sudo cp deploy/systemd/lms-backup.service deploy/systemd/lms-backup.timer /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now lms-backup.timer

Backup на том же сервере — не единственная защита: настройте выгрузку на отдельный хост и периодически проверяйте восстановление на staging.

9. Диагностика

./deploy/deploy.sh ps
./deploy/deploy.sh logs web
./deploy/deploy.sh logs gateway
./deploy/deploy.sh logs identity

Типичные проблемы:

  • web отдаёт 502 через nginx — контейнер web не поднялся: смотрите logs web. Часто причина — занят порт 8090 или не задан LMS_DB_PASSWORD (compose не стартует).
  • Страница входа открывается, но запросы падают — проверьте logs gateway и logs identity; gateway должен получить JWKS от identity.
  • 401 на страницах после входа (Docker) — у backend-сервисов не задан адрес JWKS: должно быть LMS_JWT_JWK_SET_URI=http://identity:8081/api/v1/auth/jwks.json (уже прописано в docker-compose.prod.yml для academic/progress/gateway). Внутри контейнера localhost:8081 недоступен, поэтому токен не проверяется.
  • 403/502 в профиле студента или составе группы — проверьте, что LMS_INTERNAL_TOKEN задан в .env.prod и одинаков у identity, academic и progress. При неверном внутреннем токене identity отвечает 403.
  • Не проходят загрузки больших ZIP — увеличьте client_max_body_size в nginx (сейчас 120 МБ) и spring.servlet.multipart.max-request-size.

Замечания по безопасности

  • PostgreSQL наружу не публикуется; связь между контейнерами — по внутренней сети lms.
  • Публикуется только 127.0.0.1:8090, доступ снаружи — исключительно через nginx/TLS.
  • .env.prod содержит пароль БД и не коммитится (в .gitignore).
  • Пароль администратора задаётся вами на шаге 6; хранение — BCrypt.