Развёртывание на Debian 12/13: Docker, nginx, работа за обратным прокси

- приложение перенесено в public/, инструкции в docs/
- Dockerfile (nginx без root-прав), docker-compose.yml с ограничениями
- deploy/split-trainer.conf: CSP и заголовки безопасности, no-cache по ETag,
  /healthz, реальный IP из X-Forwarded-For только от частных сетей,
  редиректы без внутреннего хоста
- deploy/install-debian.sh: установка и обновление без Docker
- docs/DEPLOY.md: требования, установка, примеры прокси (nginx, Caddy, Traefik), подпуть

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
darko
2026-10-12 12:35:47 +03:00
co-authored by Claude Sonnet 5.5
parent 42b90a056c
commit e897a6c5eb
14 changed files with 376 additions and 11 deletions
+35
View File
@@ -0,0 +1,35 @@
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Сплит-тренер</title>
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect x='2' y='8' width='12' height='16' rx='3' fill='%233b6cff'/%3E%3Crect x='18' y='8' width='12' height='16' rx='3' fill='%233b6cff'/%3E%3C/svg%3E">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="top">
<div class="brand">
<svg width="30" height="30" viewBox="0 0 32 32" aria-hidden="true"><rect x="2" y="7" width="12" height="18" rx="3" fill="currentColor"/><rect x="18" y="7" width="12" height="18" rx="3" fill="currentColor"/><g fill="var(--panel)"><rect x="5" y="11" width="2.6" height="2.6" rx=".8"/><rect x="9" y="11" width="2.6" height="2.6" rx=".8"/><rect x="5" y="16" width="2.6" height="2.6" rx=".8"/><rect x="9" y="16" width="2.6" height="2.6" rx=".8"/><rect x="21" y="11" width="2.6" height="2.6" rx=".8"/><rect x="25" y="11" width="2.6" height="2.6" rx=".8"/><rect x="21" y="16" width="2.6" height="2.6" rx=".8"/><rect x="25" y="16" width="2.6" height="2.6" rx=".8"/></g></svg>
<span>Сплит-тренер</span>
</div>
<nav id="nav" aria-label="Разделы"></nav>
</header>
<main id="app">
<section class="view" id="v-lessons"></section>
<section class="view" id="v-practice"></section>
<section class="view" id="v-keyboard"></section>
<section class="view" id="v-train"></section>
<section class="view" id="v-result"></section>
<section class="view" id="v-stats"></section>
<section class="view" id="v-settings"></section>
</main>
<div id="toast" role="status" aria-live="polite"></div>
<script src="data.js"></script>
<script src="vial.js"></script>
<script src="app.js"></script>
</body>
</html>