This commit is contained in:
2026-10-10 14:32:07 +07:00
parent 6a198f2e2c
commit 3efdb52c3c
12 changed files with 524 additions and 105 deletions
+115 -19
View File
@@ -61,20 +61,26 @@ make dev-user
По умолчанию создаётся пользователь `dev@example.com` с паролем `dev123456`.
Для изменения используйте `DEV_USER_EMAIL` и `DEV_USER_PASSWORD`.
## Автономная площадка (ED-029, этапы 1–2)
## Автономная площадка (ED-029)
`venue/` — окружение для проведения игры на площадке без интернета.
Локальная разработка описана выше и запускается отдельно.
Из корня workspace запустите:
После подготовки сертификата и локального DNS (инструкция ниже) из корня workspace запустите:
```sh
make prod-build
make venue
```
`make prod-build` заранее готовит артефакты для `prod/` и `venue/`.
Деплой не компилирует Go/Vue и не устанавливает зависимости исходного кода.
Если артефактов нет, запуск завершится с предложением выполнить `make prod-build`.
Первый запуск с интернетом сам создаёт настройки и случайные секреты в
`venue/.env`, готовит образы, запускает миграции и создаёт организатора.
Повторные запуски используют готовое окружение без интернета.
`venue/.env`, готовит Docker-образы из готовых файлов, запускает миграции и создаёт организатора.
Каждый `make venue` пересобирает Docker-образ из готовых файлов и принудительно
пересоздаёт контейнеры с HTTPS. При наличии runtime-образов и Alpine запуск
работает без интернета; отсутствующие образы скачиваются при первой подготовке.
Email и пароль для входа указаны в `VENUE_USER_EMAIL` и `VENUE_USER_PASSWORD`
в `venue/.env`; существующий файл настроек не перезаписывается.
Аккаунт организатора при запуске синхронизируется с этими значениями.
@@ -82,27 +88,25 @@ Email и пароль для входа указаны в `VENUE_USER_EMAIL` и
После изменения кода обновите площадку, пока интернет доступен:
```sh
make venue-update
make prod-build
make venue
```
Сайт доступен по `http://localhost:8088`; API и материалы обслуживаются тем же
прокси. Для подключения по LAN задайте `VENUE_BIND_IP=0.0.0.0` и
`APP_BASE_URL=http://<постоянный-IP-ноутбука>:8088` в `venue/.env`, затем
повторите `make venue`. Прежние домены и доверенный HTTPS
требуют отдельной настройки DNS и сертификатов на этапе 3.
Сайт доступен по `https://evening-detective.crabs-games.art`; API и материалы
обслуживаются тем же прокси. Для подключения по LAN задайте постоянный IP ноутбука
в `VENUE_BIND_IP` в `venue/.env` и настройте локальный DNS, как описано ниже.
Образы приложения, мигратора и прокси готовятся заранее. Runtime запускается
без сборки и скачивания; приложение, база и RustFS подключены только к
внутренней Docker-сети. Прокси дополнительно подключён к сети публикации порта.
Приложение, база и RustFS подключены только к внутренней Docker-сети.
Прокси дополнительно подключён к сети публикации порта.
База и RustFS сохраняются в именованных томах.
Миграции Goose выполняются до старта приложения. Для остановки без потери данных:
```sh
docker compose -f venue/docker-compose.yml --env-file venue/.env down
docker compose -f venue/docker-compose.yml -f venue/docker-compose.https.yml --env-file venue/.env down
```
Не используйте `down -v`: это удаляет данные. После изменений кода или миграций
выполните `make venue-update`, пока интернет доступен. Секреты, сборка,
выполните `make venue`, пока интернет доступен. Секреты, сборка,
сертификаты и пакеты игры игнорируются Git в `venue/`.
`APP_MODE=venue` отключает SMTP, фоновые письма участия/отзывов и внешний webhook
@@ -121,8 +125,7 @@ docker compose -f venue/docker-compose.yml --env-file venue/.env down
```sh
python3 tests/venue/deploy.py
python3 tests/venue/smoke.py
docker compose -f venue/docker-compose.yml --env-file venue/.env down
docker compose -f venue/docker-compose.yml --env-file venue/.env up -d --no-build --pull never
make venue
python3 tests/venue/smoke.py --verify
```
@@ -130,6 +133,98 @@ python3 tests/venue/smoke.py --verify
Тестовые данные остаются в локальной базе; повторное создание запускайте только
когда нужен новый набор. Дождитесь ответа `/api/test/ping` перед проверкой.
### Прежние домены и HTTPS (этап 3)
Подготовка в репозитории готова; проверка реального Cudy и Android/iPhone без WAN
ещё требуется. `make venue` всегда запускает HTTPS с пересборкой Docker-образа
и перезапуском контейнеров. Для первого запуска:
1. Пока интернет доступен, подготовьте артефакты через `make prod-build`.
Запуск `make venue` выполните после подготовки сертификата и локального DNS.
2. Выпустите отдельный доверенный сертификат с новым ключом для двух имён:
`evening-detective.crabs-games.art` и `evening-detective-api.crabs-games.art`.
Используйте DNS-01: проверяются TXT-записи `_acme-challenge` в публичном DNS;
публичные A/AAAA-записи production менять не нужно. Не копируйте ключ production.
Например, на машине с установленным Certbot:
```sh
certbot certonly --manual --preferred-challenges dns \
--cert-name evening-detective-venue \
-d evening-detective.crabs-games.art \
-d evening-detective-api.crabs-games.art
```
Следуйте подсказкам Certbot для TXT-записей. Выпуск сертификата выполняется
отдельно от приложения; Certbot не входит в runtime площадки.
3. Скопируйте полную цепочку (сертификат сервера и промежуточные сертификаты) в
`venue/certificates/fullchain.pem`, незашифрованный закрытый ключ — в
`venue/certificates/privkey.pem`. Ограничьте доступ к каталогу и ключу владельцем
(режимы 700 и 600); процесс Nginx в контейнере должен иметь доступ на чтение.
Каталог игнорируется Git. Перед игрой проверьте дату окончания сертификата:
```sh
openssl x509 -in venue/certificates/fullchain.pem -noout -dates
```
4. На Cudy вручную закрепите IP ноутбука и настройте локальный DNS: оба домена
должны указывать на этот IP. DHCP должен выдавать клиентам адрес локального
DNS. Возможность такой настройки проверяется на конкретной модели и прошивке;
выбор внешнего «Custom DNS» сам по себе не создаёт локальные записи.
Проверьте клиентскую изоляцию, DNS rebind protection и IPv6: клиенты должны
достигать ноутбука, а AAAA-записи не должны уводить их на production.
При отсутствии нужных возможностей прошивки остановите настройку и согласуйте
отдельное решение; скрипты проекта не меняют роутер и не прошивают его.
5. В `venue/.env` задайте `VENUE_BIND_IP=<постоянный-IP-ноутбука>` и разрешите
входящие TCP 80/443 из LAN в межсетевом экране ноутбука. Порты должны быть свободны.
Для HTTPS менять `APP_BASE_URL` в `.env` не нужно: Compose-дополнение задаёт
прежний HTTPS-домен интерфейса для QR-ссылок и материалов.
6. Запустите:
```sh
make venue
```
Команда проверяет доверие цепочке через системное хранилище OpenSSL, оба домена,
срок действия и соответствие ключа до обращения к Docker. Ошибка не переключает
работающее окружение на HTTP. Docker-образ приложения пересобирается при каждом
запуске из готовых артефактов, без компиляции Go/Vue. При наличии всех базовых
образов интернет не нужен. Доверие на реальных телефонах проверяется отдельно.
Интерфейс открывается по `https://evening-detective.crabs-games.art`, API — по
`https://evening-detective-api.crabs-games.art`. Интерфейс использует свой `/api/`;
прежний API-домен также обслуживается локально. HTTP на портах 80 и прежнем
`VENUE_PORT` перенаправляется на HTTPS с сохранением пути и параметров.
После продления сертификата с доступным интернетом замените оба PEM-файла и
повторите `make venue`: Nginx проверяет конфигурацию и перечитывает сертификат.
Продление не выполняется автоматически. После обновления кода выполните
`make prod-build`, затем `make venue`; контейнеры всегда перезапускаются с HTTPS.
Для остановки HTTPS-окружения с сохранением данных:
```sh
docker compose -f venue/docker-compose.yml -f venue/docker-compose.https.yml \
--env-file venue/.env down
```
Проверка после настройки DNS и запуска (первый smoke создаёт тестовые данные):
```sh
python3 tests/venue/smoke.py
python3 tests/venue/smoke.py --verify
```
TLS-проверка в smoke включена; самоподписанный сертификат и обход предупреждений
не подходят для приёмки. На Android и iPhone отключите WAN и мобильные данные,
подключитесь к Wi-Fi площадки и проверьте DNS обоих доменов, отсутствие TLS-ошибок,
вход организатора, материалы и QR-ссылки тестовой игры. Повторите после перезапуска.
Проверьте запрос доступа к камере отдельно: распознавание QR в текущем интерфейсе
также требует поддержки браузером `BarcodeDetector`.
Этап 3 сохраняет адреса, но не переносит данные production. Production-QR может
вести на игру или билет, которых в локальной базе ещё нет; перенос и возврат
данных относятся к этапам 4–11. До их завершения используйте только тестовые игры.
## Проверки перед изменениями
Сервер:
@@ -178,8 +273,9 @@ API через свой прокси (`VITE_API_URL=/.`). Локальные Goo
make build
```
`make prod-build` выполняет ту же общую сборку. `make venue-update` вызывает её
и дополнительно подготавливает Docker-образы для автономного запуска. Команды
`make prod-build` выполняет ту же общую сборку. `make venue` пересобирает
Docker-образ из готовых артефактов и перезапускает площадку с HTTPS.
`make venue-update` и `make venue-https` сохранены как алиасы `make venue`. Команды
обновляют только генерируемые артефакты в `prod`; конфигурация `prod` не меняется.
## Окружение и секреты