Система управления расписанием и пересдачами на Astro + Vue + FastAPI + PostgreSQL + Redis.
В репозитории есть два основных режима запуска:
docker-compose.ymlдля локальной разработкиdocker-compose.prod.ymlиdocker-compose.prod.https.ymlдля production
src/— фронтенд на Astro/Vuebackend/— backend на FastAPIdocker-compose.yml— dev-окружениеdocker-compose.prod.yml— production через reverse proxy по HTTPdocker-compose.prod.https.yml— production через reverse proxy с HTTPSinfra/nginx/— конфиги nginxinfra/scripts/— скрипты бэкапа и восстановления Postgres
- Docker Desktop с
docker compose - Git
Локально вне Docker ничего отдельно ставить не требуется: и фронтенд, и backend запускаются в контейнерах.
Скопируйте шаблон:
Copy-Item .env.example .envДля dev обычно достаточно значений из .env.example.
docker compose up --build -dПосле старта будут доступны:
- фронтенд: http://localhost:4321
- backend API: http://localhost:8000/api
- docs в dev: http://localhost:8000/docs
docker compose pscurl http://localhost:8000/api/healthОжидается ответ со статусом ok.
Поднять всё:
docker compose up --build -dОстановить всё:
docker compose downОстановить всё с удалением томов базы и Redis:
docker compose down -vПосмотреть логи backend:
docker compose logs -f backendПосмотреть логи frontend:
docker compose logs -f frontendПрогнать миграции вручную:
docker compose exec backend alembic upgrade headПосле первого запуска база будет пустой. Создайте первого пользователя с ролью ADMIN через встроенный backend-скрипт.
Для dev:
docker compose exec backend python -m app.scripts.create_admin --username admin --password CHANGE_ME_NOW --full-name "System Administrator"Для production:
docker compose -f docker-compose.prod.yml exec backend python -m app.scripts.create_admin --username admin --password CHANGE_ME_NOW --full-name "System Administrator"Что делает эта команда:
- создает активного пользователя с ролью
ADMIN - ставит флаг обязательной смены пароля при первом входе
- не привязывает пользователя к преподавателю
После входа в систему такой пользователь будет обязан сменить временный пароль.
После входа под первым администратором:
- Откройте админ-панель.
- Создайте преподавателей или синхронизируйте справочник.
- Создайте учетные записи для нужных преподавателей и сотрудников.
- Передайте временный пароль пользователю.
- Пользователь при первом входе сменит пароль принудительно.
Основные переменные находятся в:
.env.example— dev-шаблон.env.production.example— production-шаблон
Самые важные настройки:
APP_ENV—developmentилиproductionDEBUG— в production должно бытьfalseSESSION_SECRET_KEY— длинный случайный секрет для cookie-сессийFRONTEND_ORIGINS— разрешенные frontend originCSRF_TRUSTED_ORIGINS— trusted origin для unsafe-запросовSESSION_SAME_SITE— политика cookieSESSION_COOKIE_DOMAIN— общий cookie domain, если нуженAPI_DOCS_ENABLED— включать ли/docsALLOW_ORIGINLESS_UNSAFE_REQUESTS— в production должно бытьfalse
В проекте используется cookie-based session auth.
Сейчас уже реализованы:
- хеширование паролей
- rate limiting на логин и смену пароля
- CSRF token для state-changing запросов
- проверка
Origin/Referer - инвалидирование старых сессий после смены пароля
- обязательная смена стартового пароля
- audit log для входов и админских действий
Подходит, если HTTPS завершается внешним ingress, load balancer или CDN.
Скопируйте шаблон:
Copy-Item .env.production.example .envОбязательно замените:
POSTGRES_PASSWORDSESSION_SECRET_KEYRASPYX_USERNAMERASPYX_PASSWORDFRONTEND_ORIGINSCSRF_TRUSTED_ORIGINS
docker compose -f docker-compose.prod.yml up --build -ddocker compose -f docker-compose.prod.yml psПодходит, если сертификаты лежат прямо на сервере.
Copy-Item .env.production.example .envНужны файлы:
infra/certs/fullchain.peminfra/certs/privkey.pem
docker compose -f docker-compose.prod.https.yml up --build -ddocker compose -f docker-compose.prod.https.yml ps.gitignore уже исключает .env, но если файл раньше был добавлен в git, этого недостаточно.
Нужно выполнить один раз:
git rm --cached .envВ production не должны быть доступны извне:
800054326379
Во внешнюю сеть должен смотреть только reverse proxy.
Для production:
APP_ENV=productionDEBUG=falseAPI_DOCS_ENABLED=falseALLOW_ORIGINLESS_UNSAFE_REQUESTS=false
Если фронтенд и API идут через один origin:
- используйте
SESSION_SAME_SITE=lax SESSION_COOKIE_DOMAINможно оставить пустым
Если используются разные поддомены:
- настройте общий
SESSION_COOKIE_DOMAIN, например.example.com - при необходимости используйте
SESSION_SAME_SITE=none - режим
noneбезопасно использовать только с HTTPS
Обычно на публичном сервере наружу должны быть открыты только:
80443
После запуска production стека выполните:
docker compose -f docker-compose.prod.yml exec backend python -m app.scripts.create_admin --username admin --password CHANGE_ME_NOW --full-name "System Administrator"Если используется HTTPS compose:
docker compose -f docker-compose.prod.https.yml exec backend python -m app.scripts.create_admin --username admin --password CHANGE_ME_NOW --full-name "System Administrator"- заполнен production
.env - секреты заменены на реальные
.envубран из git tracking- включен HTTPS
- наружу не опубликованы
8000,5432,6379 /docsотключен- первый
ADMINсоздан - вход, выход и смена пароля работают
- преподаватель не может открыть чужое расписание
- audit log записывает входы и админские действия
Сейчас audit log пишет:
- успешные и неуспешные входы
- выход из системы
- смену пароля
- создание, изменение и удаление пользователей
- операции по кафедрам и должностям
- операции по преподавателям и справочнику
- операции со снимками расписания
- часть административных действий по пересдачам
В админке есть отдельная вкладка журнала действий с:
- поиском
- фильтром по действию
- фильтром по статусу
- пагинацией
Скрипты лежат в infra/scripts/.
Бэкап:
sh infra/scripts/postgres-backup.shВосстановление:
sh infra/scripts/postgres-restore.sh ./backups/postgres_YYYYMMDD_HHMMSS.sqlПеред восстановлением убедитесь, что понимаете последствия для боевой базы.
docker compose down -v
docker compose up --build -dПосле этого база будет пустой, и первого администратора нужно будет создать заново.
Это уже не блокеры для первого запуска, но хорошие следующие шаги:
- вывести audit log в отдельный API export
- добавить фильтр по пользователю в audit log
- добавить 2FA хотя бы для
ADMIN - вынести TLS на внешний ingress или load balancer
- настроить автоматические backup job
- добавить CI-проверки зависимостей и secret scanning