go-learn/docs/deploy.md
sab.code.lab 1c85091186 chore: восстановление репозитория из снапшота v0.3.1
Прежняя git-история утрачена при переносе проекта на машину владельца
(снапшот без .git). Хэши коммитов в docs/reports/* относятся к утраченной
истории.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 09:34:02 +02:00

101 lines
6.3 KiB
Markdown
Raw Permalink 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.

# Деплой на shared-хостинг (чек-лист, V.2)
Дата: 2026-08-06. Выполняет ВЛАДЕЛЕЦ руками (V.1: агент прод не трогает).
Проходить целиком, частичные варианты запрещены (gotcha-partial-build).
## Артефакты деплоя (ВСЕ, их ТРИ)
1. **Статика сайта**: `apps/web/dist/` → web root хостинга (например,
`public_html/`). Сборка: `npm ci && npm run build` в `apps/web`
(Node 20+, локально) либо взять готовый dist из превью-версии.
2. **API**: содержимое `server/` раскладывается по web root ЧАСТЯМИ
(не целиком!): `server/api/``public_html/api/`,
`server/lib/``public_html/lib/`. Эндпоинты оказываются доступны
как `/api/*.php`. Пути жёсткие: PHP-файлы ищут lib как `../lib/`
(smoke-тест локально поднимает docroot = server/, поэтому на проде
web root = dist + содержимое server/).
3. **Конфиг + БД**: скопировать `server/config.example.php`
`public_html/config.php` (именно в КОРЕНЬ web root — db.php ищет его
как `__DIR__.'/../config.php'` от lib/), выставить `db_path` — путь
ВНЕ web root (например, `/home/<user>/go-learn.sqlite`). Сам файл БД
создастся сам при первом обращении (права на каталог — записываемые
для PHP). Также выставить `base_url` (полный URL сайта — идёт в письма
восстановления пароля) и `mail_from` (отправитель писем).
## Итоговая структура на хостинге
```text
public_html/
├── index.html, learn.html, play.html, … ← из dist (артефакт 1)
├── _astro/, assets/ ← из dist
├── .htaccess ← из dist + блок запрета ниже
├── api/ ← server/api/ (артефакт 2)
│ ├── health.php, register.php, login.php, logout.php, me.php,
│ ├── progress.php, captcha.php
│ └── password-reset/ (request.php, confirm.php)
├── lib/ ← server/lib/
│ └── auth.php, db.php, http.php, ratelimit.php
└── config.php ← созданный вручную (артефакт 3)
```
В корневой `.htaccess` (из dist) дописать блок из server/.htaccess:
```apache
<IfModule mod_authz_core.c>
<FilesMatch "(^config\.php$|\.sqlite(-wal|-shm)?$)">
Require all denied
</FilesMatch>
</IfModule>
```
## Порядок (каждый шаг — отдельное действие)
0. Проверки хостинга: PHP ≥ 8.0, модули pdo_sqlite, sqlite3
(phpinfo в панели или `php -v`/`php -m` по SSH, если есть).
Нет pdo_sqlite — стоп, вопрос хостеру.
1. Залить dist (артефакт 1).
2. Залить server/ (артефакт 2) и создать config.php (артефакт 3).
3. Smoke: открыть `/api/health.php` → ожидается `{"status":"ok"}`.
Не 200/не JSON — смотреть логи PHP в панели, НЕ править код на глазах.
4. Smoke вручную: регистрация на странице /register.html (с капчей)
→ вход → «Синхронизировать прогресс» → статус «Прогресс отправлен».
4.1. Проверка почты (этап 8.1): «Забыли пароль?» на /account.html →
письмо со ссылкой приходит и ссылка ведёт на
/password-reset.html?token=…. Не приходит — смотреть настройки
SPF/DKIM в панели хостинга; до решения восстановление считать
нерабочим (риск в PROJECT_STATE).
5. Проверить, что БД-файл появился по пути из config.php и НЕ доступен
по HTTP (попытка открыть его URL → 403/404).
6. HTTPS — включать ТОЛЬКО панелью хостинга (в .htaccess редиректа нет
намеренно, gotcha-https-redirect-proxy). После включения — повторить
шаги 34 по HTTPS.
## Канонические пути (V.5) — заполнить при первом деплое
- Web root: `____________`
- URL сайта: `____________`
- Путь БД (вне web root): `____________`
- Дата первого деплоя: `____________`
## Откат
Откат = перезаливка предыдущего dist и (при изменении server/) предыдущего
server/. Схема БД этапа 8 аддитивна (init-only), обратной миграции нет;
перед любым изменением схемы в будущем — дамп БД ДО деплоя (V.3).
## Бэкап и restore (V.7, минимум)
- Бэкап = копия файла SQLite (из панели файлового менеджера/SSH) +
config.php. Периодичность — после заметного роста числа пользователей
(ручная, SoT расписания — этот файл).
- Restore: остановить запись (выключить сайт в панели) → вернуть файл БД
на путь из config.php → smoke шаг 34. Проверка restore выполняется на
первом же бэкапе: распаковать копию под другим именем и открыть
`sqlite3 <файл> "SELECT count(*) FROM users;"` (или через панель).
## Чего НЕ делать
- Не класть config.php и БД в web root.
- Не включать HTTPS-редирект в .htaccess (только панель).
- Не править PHP/БД на проде напрямую: правка → локальный smoke.sh →
перезаливка.