Files
LMS/deploy/DEPLOY.md

160 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Деплой 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
```bash
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker "$USER" # перелогиньтесь, чтобы работать без sudo
docker compose version # нужна версия v2
```
## 2. Получить код
```bash
sudo mkdir -p /opt/lms && sudo chown "$USER" /opt/lms
git clone <URL-репозитория> /opt/lms
cd /opt/lms
```
## 3. Настроить окружение
```bash
cp .env.prod.example .env.prod
nano .env.prod
```
Обязательно задайте надёжный `LMS_DB_PASSWORD`. Остальные значения по умолчанию подходят.
## 4. Собрать и запустить
```bash
./deploy/deploy.sh up
```
Скрипт соберёт образы (первый раз ~5–15 минут: скачиваются Gradle и зависимости)
и поднимет контейнеры. Проверка:
```bash
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
```bash
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`](IMPORT.md). Файлы со списками студентов и выгрузками паролей —
персональные данные, держите их вне репозитория.
## 7. Обновление версии
```bash
cd /opt/lms
git pull
./deploy/deploy.sh up # backup → сборка → миграции → перезапуск
```
`deploy.sh up` **обязательно** делает backup перед обновлением. Если backup
завершился ошибкой, деплой прерывается. Миграции БД (Flyway) применяются
автоматически при старте сервисов.
## 8. Резервное копирование
Полная инструкция — [`BACKUP.md`](BACKUP.md). Кратко:
```bash
./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`).
Ежедневное расписание:
```bash
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. Диагностика
```bash
./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` недоступен, поэтому токен не проверяется.
- **Не проходят загрузки больших 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.