5.7 KiB
LMS: практические занятия по курсу «Промышленное программирование на C»
Минимальное ядро: регистрация, списки студентов, варианты лабораторных и их распределение. Условие своего варианта студент видит в личном кабинете.
Два микросервиса:
- lms-api (
src/backend/lms_api, :8000) — данные и логика (SQLite), REST/api/v1; - lms-web (
src/frontend/lms_web, :8080) — веб-интерфейс, ходит в API по HTTP.
Запуск
make install # .venv + зависимости
make dev # lms-api :8000 + lms-web :8080
# открыть http://127.0.0.1:8080 — при первом запуске создать аккаунт преподавателя
Тесты: make test (11 проверок, свои порты/БД). В Docker: make build && make up
(или make deploy); данные — в volume lms_data.
Возможности сейчас
Преподаватель
- аккаунт администратора (единственный), смена пароля;
- Лабораторные — создаются из JSON-файла с вариантами (см.
examples/lab1.json):variantsсlevel: main/advanced, номером, условием, примерами и указаниями; если срок сдачи в JSON не задан — автоматически ставится через 25 дней (3 недели и 4 дня) после создания; - Группы — импорт списков из
.xls/.xlsx(название из шапки, столбцы: № п/п, студенческий номер, ФИО, основа обучения); новым студентам генерируется пароль (логин = номер студенческого), выгрузка «ФИО, логин, пароль» (xlsx/csv), сброс пароля; - Распределение вариантов: студенту выбирается уровень (основная / повышенная), затем по группе раздаются варианты конкретной лабораторной (уникальны внутри группы, по возможности — между группами; если вариантов меньше студентов — допустимы повторы), есть ручное назначение номера.
Студент
- вход по номеру студенческого и паролю; при первом входе смена пароля обязательна;
- список работ и условие своего варианта (по каждой работе — с примерами входов/выходов и указаниями).
Остальное (отправка решений, задания на защиту/добор, тренировочные задачи, оценки) будет добавлено позднее.
Формат JSON лабораторной (examples/lab1.json)
{
"number": 1,
"title": "Одномерные массивы и последовательности",
"semester": "осень",
"deadline": "2026-10-01T23:59",
"points_max": 5,
"goal": "…", "common_requirements": "…",
"variants": [
{ "level": "main", "number": "1", "statement": "…",
"examples": [ { "input": "4\n1 2 3 4", "output": "10", "explanation": "…" } ],
"notes": "…" },
{ "level": "advanced", "number": "21", "statement": "…" }
]
}
Деплой на сервер
Вариант 1 — Docker (рекомендую)
# на сервере: скопировать проект, затем
cp .env.example .env
nano .env # FRONTEND_PORT=8080 (или 80), API_PORT=8000
./deploy.sh # соберёт образы и поднимет сервисы
docker compose ps # статус
docker compose logs -f # логи
Данные (БД и загрузки) хранятся в volume lms_data — переживают перезапуск
и пересборку. Бэкап одной командой:
docker run --rm -v lms_lms_data:/data -v $PWD:/backup alpine tar czf /backup/lms-backup.tar.gz /data
Порты для наружу: пользователям нужен только lms-web (по умолчанию :8080).
lms-api достаточно оставить внутри сети compose (в .env не публиковать
API_PORT, либо ограничить доступ файрволом).
Вариант 2 — без Docker (процессы через systemd)
make install
# два юнита (пример /etc/systemd/system/lms-api.service):
# ExecStart=/path/to/lms/.venv/bin/python -m uvicorn lms_api.main:app
# --app-dir /path/to/lms/src/backend --host 0.0.0.0 --port 8000
# Environment=LMS_API_URL=http://127.0.0.1:8000
# и аналогично lms-web на --host 0.0.0.0 --port 8080 (lms_web.main:app, src/frontend)
Удобно поставить lms-web за nginx (HTTPS, отдача статики проксируется на :8080),
доступ к /api/v1/* на :8080 не требуется наружу.
Структура
src/backend/lms_api/ # API: core/{db,security,variants,xls_import}, routers
src/frontend/lms_web/ # веб: routers, templates, static
tests/smoke_test.py # make test
examples/ # ПИ-11БО.xls, ПИ-12БО.xls, lab1.json
Dockerfile docker-compose.yml deploy.sh Makefile data/