SHA256
Зафиксировать накопленные изменения по deploy и devnet
This commit is contained in:
@@ -0,0 +1,72 @@
|
|||||||
|
# Production-серверы SHiNE
|
||||||
|
|
||||||
|
## Короткий ответ
|
||||||
|
|
||||||
|
По текущим данным репозитория у SHiNE формально описан **один production-хост**:
|
||||||
|
|
||||||
|
- `player@shineup.me`
|
||||||
|
- домен `shineup.me`
|
||||||
|
- IP `185.229.109.118`
|
||||||
|
|
||||||
|
Второй отдельный production-хост в текущих проектных инструкциях **не описан**.
|
||||||
|
Остальные известные серверы в репозитории относятся к test-контурам.
|
||||||
|
|
||||||
|
## 1. Основной production-хост
|
||||||
|
|
||||||
|
- SSH: `player@shineup.me`
|
||||||
|
- домен: `shineup.me`
|
||||||
|
- IP: `185.229.109.118`
|
||||||
|
- пользователь: `player`
|
||||||
|
- базовый путь: `/home/player`
|
||||||
|
|
||||||
|
Основные каталоги:
|
||||||
|
|
||||||
|
- проект SHiNE: `/home/player/SHiNE`
|
||||||
|
- серверный jar: `/home/player/SHiNE/shine-server/shine-server.jar`
|
||||||
|
- UI: `/home/player/SHiNE/shine-ui`
|
||||||
|
- данные: `/home/player/SHiNE/shine-server/data/`
|
||||||
|
- логи: `/home/player/SHiNE/shine-server/logs/app.log`
|
||||||
|
|
||||||
|
Сервисы:
|
||||||
|
|
||||||
|
- `shine-server.service`
|
||||||
|
- `caddy.service`
|
||||||
|
|
||||||
|
Caddy:
|
||||||
|
|
||||||
|
- активный конфиг: `/home/player/SHiNE/caddy/Caddyfile`
|
||||||
|
- UI root: `/home/player/SHiNE/shine-ui`
|
||||||
|
- `/ws` проксируется на `127.0.0.1:7070`
|
||||||
|
|
||||||
|
Deploy:
|
||||||
|
|
||||||
|
- `./gradlew deployServerProduction`
|
||||||
|
- `./gradlew deployUIProduction`
|
||||||
|
|
||||||
|
Правило:
|
||||||
|
|
||||||
|
- любые изменения на `shineup.me` делать только после отдельного подтверждения пользователя.
|
||||||
|
|
||||||
|
## 2. Связанные публичные production-публикации на том же хосте
|
||||||
|
|
||||||
|
На этом же production-хосте есть отдельная публикация для `shine_payments`:
|
||||||
|
|
||||||
|
- каталог: `/home/player/sites/test-solana-tickets.shineup.me`
|
||||||
|
- домены:
|
||||||
|
- `https://test-solana-tickets.shineup.me`
|
||||||
|
- `https://test-solana-tickets.shiningpeople.ru`
|
||||||
|
|
||||||
|
Это не второй production-хост SHiNE, а отдельный сайт на том же сервере.
|
||||||
|
|
||||||
|
## 3. Какие серверы не считать production
|
||||||
|
|
||||||
|
Не production:
|
||||||
|
|
||||||
|
- `t.shineup.me` (`193.8.215.70`) — основной test
|
||||||
|
- `test.shineup.me` (`93.170.12.154`) — резервный test
|
||||||
|
- `t1.shineup.me`
|
||||||
|
- `t2.shineup.me`
|
||||||
|
- `t3.shineup.me`
|
||||||
|
- `t4.shineup.me`
|
||||||
|
|
||||||
|
Если позже появится второй отдельный production-хост, его нужно явно добавить в этот файл.
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# Deploy
|
||||||
|
|
||||||
|
Подробности о том, где что задеплоено в SHiNE, нужно искать в папке `Deploy/`.
|
||||||
|
|
||||||
|
Эта папка служит краткой картой окружений:
|
||||||
|
|
||||||
|
- [TEST_SERVERS.md](/home/ai/work/SHiNE/SHiNE-server-sha256/Deploy/TEST_SERVERS.md) — тестовые серверы и стенды;
|
||||||
|
- [PRODUCTION_SERVERS.md](/home/ai/work/SHiNE/SHiNE-server-sha256/Deploy/PRODUCTION_SERVERS.md) — production-контур и связанные публичные публикации.
|
||||||
|
|
||||||
|
Ниже краткая сводка.
|
||||||
|
|
||||||
|
## Основные публичные контуры
|
||||||
|
|
||||||
|
- Production SHiNE:
|
||||||
|
- `player@shineup.me`
|
||||||
|
- домен `shineup.me`
|
||||||
|
- IP `185.229.109.118`
|
||||||
|
- Main test:
|
||||||
|
- `player@193.8.215.70`
|
||||||
|
- домен `t.shineup.me`
|
||||||
|
- IP `193.8.215.70`
|
||||||
|
- Reserve test:
|
||||||
|
- `player@93.170.12.154`
|
||||||
|
- домен `test.shineup.me`
|
||||||
|
- IP `93.170.12.154`
|
||||||
|
|
||||||
|
## Отдельный quad-devnet стенд
|
||||||
|
|
||||||
|
На отдельном VPS `178.208.90.249` подняты 4 независимых test/devnet-инстанса:
|
||||||
|
|
||||||
|
- `t1.shineup.me`
|
||||||
|
- `t2.shineup.me`
|
||||||
|
- `t3.shineup.me`
|
||||||
|
- `t4.shineup.me`
|
||||||
|
|
||||||
|
## Важно
|
||||||
|
|
||||||
|
- Формально production-хост SHiNE в текущем репозитории описан один: `shineup.me`.
|
||||||
|
- `t.shineup.me`, `test.shineup.me`, `t1..t4.shineup.me` — это тестовые контуры, не production.
|
||||||
|
- Любые изменения на `shineup.me` делать только после отдельного подтверждения пользователя.
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
# Тестовые серверы SHiNE
|
||||||
|
|
||||||
|
Этот файл описывает тестовые контуры, которые сейчас фигурируют в проекте.
|
||||||
|
|
||||||
|
## 1. Основной test-сервер
|
||||||
|
|
||||||
|
- SSH: `player@193.8.215.70`
|
||||||
|
- Домен: `t.shineup.me`
|
||||||
|
- IP: `193.8.215.70`
|
||||||
|
- Назначение: основной test для обычных `deployServer` / `deployUI`
|
||||||
|
|
||||||
|
Структура:
|
||||||
|
|
||||||
|
- каталог SHiNE: `/home/player/SHiNE`
|
||||||
|
- сервер: `/home/player/SHiNE/shine-server/shine-server.jar`
|
||||||
|
- UI: `/home/player/SHiNE/shine-ui`
|
||||||
|
- данные: `/home/player/SHiNE/shine-server/data/`
|
||||||
|
- логи: `/home/player/SHiNE/shine-server/logs/app.log`
|
||||||
|
|
||||||
|
Сервисы:
|
||||||
|
|
||||||
|
- `shine-server.service`
|
||||||
|
- `caddy.service`
|
||||||
|
|
||||||
|
Deploy:
|
||||||
|
|
||||||
|
- `./gradlew deployServer`
|
||||||
|
- `./gradlew deployServerTest2`
|
||||||
|
- `./gradlew deployUI`
|
||||||
|
- `./gradlew deployUITest2`
|
||||||
|
|
||||||
|
Примечания:
|
||||||
|
|
||||||
|
- это основной тестовый контур;
|
||||||
|
- default deploy по проекту должен идти сюда;
|
||||||
|
- тестовая БД синхронизируется от production `shineup.me`.
|
||||||
|
|
||||||
|
## 2. Резервный test-сервер
|
||||||
|
|
||||||
|
- SSH: `player@93.170.12.154`
|
||||||
|
- Домен: `test.shineup.me`
|
||||||
|
- IP: `93.170.12.154`
|
||||||
|
- Назначение: резервный test
|
||||||
|
|
||||||
|
Структура по проектным докам:
|
||||||
|
|
||||||
|
- каталог SHiNE: `/home/player/SHiNE`
|
||||||
|
- сервер: `/home/player/SHiNE/shine-server/shine-server.jar`
|
||||||
|
- UI: `/home/player/SHiNE/shine-ui`
|
||||||
|
- данные: `/home/player/SHiNE/shine-server/data/`
|
||||||
|
- логи: `/home/player/SHiNE/shine-server/logs/app.log`
|
||||||
|
|
||||||
|
Deploy:
|
||||||
|
|
||||||
|
- `./gradlew deployServerTest`
|
||||||
|
- `./gradlew deployUITest`
|
||||||
|
|
||||||
|
Примечания:
|
||||||
|
|
||||||
|
- этот хост резервный;
|
||||||
|
- использовать его без отдельной причины не нужно.
|
||||||
|
|
||||||
|
## 3. Отдельный quad-devnet стенд `t1..t4`
|
||||||
|
|
||||||
|
- VPS: `178.208.90.249`
|
||||||
|
- пользователь: `player`
|
||||||
|
- назначение: 4 независимых SHiNE-инстанса на Solana `devnet`
|
||||||
|
|
||||||
|
Домены и логины:
|
||||||
|
|
||||||
|
- `server_t1` -> `https://t1.shineup.me`
|
||||||
|
- `server_t2` -> `https://t2.shineup.me`
|
||||||
|
- `server_t3` -> `https://t3.shineup.me`
|
||||||
|
- `server_t4` -> `https://t4.shineup.me`
|
||||||
|
|
||||||
|
Каталоги:
|
||||||
|
|
||||||
|
- `/home/player/t1/server`
|
||||||
|
- `/home/player/t1/UI`
|
||||||
|
- `/home/player/t2/server`
|
||||||
|
- `/home/player/t2/UI`
|
||||||
|
- `/home/player/t3/server`
|
||||||
|
- `/home/player/t3/UI`
|
||||||
|
- `/home/player/t4/server`
|
||||||
|
- `/home/player/t4/UI`
|
||||||
|
|
||||||
|
Подробная памятка на самом VPS:
|
||||||
|
|
||||||
|
- `/home/player/Agents.md`
|
||||||
|
|
||||||
|
Порты и systemd:
|
||||||
|
|
||||||
|
- `t1` -> `7101` -> `shine-t1.service`
|
||||||
|
- `t2` -> `7102` -> `shine-t2.service`
|
||||||
|
- `t3` -> `7103` -> `shine-t3.service`
|
||||||
|
- `t4` -> `7104` -> `shine-t4.service`
|
||||||
|
|
||||||
|
Что важно по конфигу каждого инстанса:
|
||||||
|
|
||||||
|
- отдельный `/home/player/tX/server/application.properties`
|
||||||
|
- `server.port=710X`
|
||||||
|
- `server.SHiNE.login=server_tX`
|
||||||
|
- `db.path=data/shine.sqlite`
|
||||||
|
- `solana.cluster=devnet`
|
||||||
|
- `solana.rpcUrl=https://api.devnet.solana.com`
|
||||||
|
- `server.ui.indexPath=/home/player/tX/UI/index.html`
|
||||||
|
- `server.info.url=https://tX.shineup.me`
|
||||||
|
|
||||||
|
UI каждого инстанса:
|
||||||
|
|
||||||
|
- живёт в отдельной копии `shine-UI`;
|
||||||
|
- использует свой `js/deploy-config.js`;
|
||||||
|
- по умолчанию смотрит именно на свой `tX.shineup.me`.
|
||||||
|
|
||||||
|
Caddy на стенде:
|
||||||
|
|
||||||
|
- конфиг: `/etc/caddy/Caddyfile`
|
||||||
|
- статика: `/home/player/tX/UI`
|
||||||
|
- `/ws` проксируется на `127.0.0.1:710X`
|
||||||
|
|
||||||
|
Operational-нюанс:
|
||||||
|
|
||||||
|
- при одновременных рестартах возможны `HTTP 429` от `api.devnet.solana.com`;
|
||||||
|
- поэтому сервисы `shine-t1..shine-t4` лучше перезапускать по одному, с паузой.
|
||||||
|
|
||||||
|
## 4. Что проверять первым делом
|
||||||
|
|
||||||
|
Для любого test-контура полезны такие быстрые проверки:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -I https://t.shineup.me
|
||||||
|
curl -I https://test.shineup.me
|
||||||
|
curl -I https://t1.shineup.me
|
||||||
|
curl -I https://t2.shineup.me
|
||||||
|
curl -I https://t3.shineup.me
|
||||||
|
curl -I https://t4.shineup.me
|
||||||
|
```
|
||||||
|
|
||||||
|
Для quad-devnet VPS:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl --no-pager --full status caddy shine-t1 shine-t2 shine-t3 shine-t4
|
||||||
|
```
|
||||||
|
|
||||||
|
Для основного/резервного test:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl --no-pager --full status shine-server caddy
|
||||||
|
```
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
# Изоляция страницы DEVNET пополнения от mainnet
|
|
||||||
|
|
||||||
- краткое описание фичи:
|
|
||||||
Страница `shine-UI/js/pages/devnet-topup-view.js` переведена на полностью автономную работу только с `https://api.devnet.solana.com`. Проверка баланса и перевод SOL на этой странице больше не используют общие Solana-настройки UI.
|
|
||||||
- что именно проверять:
|
|
||||||
1. Открыть страницу `devnet-topup-view` с параметром `wallet`.
|
|
||||||
2. Убедиться, что на странице отображается сеть `DEVNET`.
|
|
||||||
3. Проверить, что балансы отправителя и получателя читаются из devnet.
|
|
||||||
4. Выполнить перевод и убедиться, что транзакция проходит именно в devnet.
|
|
||||||
5. Убедиться, что изменение глобального Solana endpoint в других экранах UI не влияет на эту страницу.
|
|
||||||
- ожидаемый результат:
|
|
||||||
Страница всегда показывает devnet-балансы и отправляет перевод только через devnet, независимо от глобального RPC в приложении.
|
|
||||||
- статус:
|
|
||||||
pending
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# 4 тестовых SHiNE-сервера на одном VPS (`178.208.90.249`)
|
||||||
|
|
||||||
|
- статус: `pending`
|
||||||
|
|
||||||
|
## Кратко
|
||||||
|
|
||||||
|
Поднят отдельный тестовый стенд:
|
||||||
|
- `t1.shineup.me`
|
||||||
|
- `t2.shineup.me`
|
||||||
|
- `t3.shineup.me`
|
||||||
|
- `t4.shineup.me`
|
||||||
|
|
||||||
|
Каждый домен ведёт на свой SHiNE-инстанс под пользователем `player`, все инстансы работают через Solana `devnet`.
|
||||||
|
|
||||||
|
## Что проверять
|
||||||
|
|
||||||
|
- UI каждого домена открывается без ошибок:
|
||||||
|
- `https://t1.shineup.me`
|
||||||
|
- `https://t2.shineup.me`
|
||||||
|
- `https://t3.shineup.me`
|
||||||
|
- `https://t4.shineup.me`
|
||||||
|
- регистрация/логин клиента может работать через каждый из этих серверов
|
||||||
|
- WebSocket-подключение реально идёт на свой инстанс, а не в соседний
|
||||||
|
- чтение PDA и server-ui формы по умолчанию используют `devnet`
|
||||||
|
- межсерверный sync после ручных тестов действительно использует `access_servers/sync_servers`
|
||||||
|
- не происходит путаницы данных между `t1/t2/t3/t4`
|
||||||
|
|
||||||
|
## Ожидаемый результат
|
||||||
|
|
||||||
|
- каждый домен работает независимо
|
||||||
|
- у каждого инстанса своя БД и свои локальные данные
|
||||||
|
- `Caddy` корректно проксирует `/ws` на `7101..7104`
|
||||||
|
- серверы не падают после старта
|
||||||
|
- если devnet RPC временно даёт `429`, последовательный рестарт по одному инстансу позволяет подтянуть `sync_servers`
|
||||||
|
|
||||||
|
## Примечание
|
||||||
|
|
||||||
|
Подробная схема размещения описана в:
|
||||||
|
- [Dev_Docs/deploy/test-server/178.208.90.249_quad_devnet.md](/home/ai/work/SHiNE/SHiNE-server-sha256/Dev_Docs/deploy/test-server/178.208.90.249_quad_devnet.md)
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
Lf dc` hfm# TURN: только один живой узел для звонков
|
||||||
|
|
||||||
|
- краткое описание:
|
||||||
|
- в серверном конфиге оставлен только один TURN-узел `185.229.109.118:3478` для ICE-конфига звонков;
|
||||||
|
- мёртвый узел `93.170.12.154:3478` убран из локальной конфигурации и test-деплоя `t2`.
|
||||||
|
- что проверять:
|
||||||
|
- открыть два клиента на `t2.shineup.me`;
|
||||||
|
- начать аудиозвонок между ними;
|
||||||
|
- убедиться, что `GetCallIceConfig` отдаёт только TURN `185.229.109.118`;
|
||||||
|
- убедиться, что звонок выходит из стадии `connecting` и появляется `call_connected` либо как минимум `relay`-кандидаты в клиентской диагностике.
|
||||||
|
- ожидаемый результат:
|
||||||
|
- клиентам больше не предлагается `93.170.12.154`;
|
||||||
|
- звонок проходит стабильнее, чем до изменения;
|
||||||
|
- в серверных логах нет новых `incoming_failed/outgoing_failed` только из-за нерабочего TURN.
|
||||||
|
- статус:
|
||||||
|
- pending
|
||||||
@@ -38,6 +38,11 @@
|
|||||||
- Reserve test UI deploy: `./gradlew deployUITest`
|
- Reserve test UI deploy: `./gradlew deployUITest`
|
||||||
- Локальный запуск: `./gradlew startLocal`
|
- Локальный запуск: `./gradlew startLocal`
|
||||||
|
|
||||||
|
## Отдельные тестовые VPS
|
||||||
|
|
||||||
|
- Отдельный стенд с 4 devnet-серверами на одном VPS описан в:
|
||||||
|
- `Dev_Docs/deploy/test-server/README.md`
|
||||||
|
|
||||||
## Политика подтверждений
|
## Политика подтверждений
|
||||||
|
|
||||||
- `shineup.me` — production.
|
- `shineup.me` — production.
|
||||||
|
|||||||
@@ -0,0 +1,173 @@
|
|||||||
|
# VPS `178.208.90.249` (`player`) — 4 тестовых SHiNE-сервера на devnet
|
||||||
|
|
||||||
|
## Назначение
|
||||||
|
|
||||||
|
Этот VPS используется как отдельный тестовый стенд для одновременного запуска 4 SHiNE-серверов:
|
||||||
|
- `server_t1` → `https://t1.shineup.me`
|
||||||
|
- `server_t2` → `https://t2.shineup.me`
|
||||||
|
- `server_t3` → `https://t3.shineup.me`
|
||||||
|
- `server_t4` → `https://t4.shineup.me`
|
||||||
|
|
||||||
|
Все 4 инстанса работают через Solana `devnet`.
|
||||||
|
|
||||||
|
## Каталоги
|
||||||
|
|
||||||
|
Структура в домашней папке пользователя `player`:
|
||||||
|
- `/home/player/t1/server`
|
||||||
|
- `/home/player/t1/UI`
|
||||||
|
- `/home/player/t2/server`
|
||||||
|
- `/home/player/t2/UI`
|
||||||
|
- `/home/player/t3/server`
|
||||||
|
- `/home/player/t3/UI`
|
||||||
|
- `/home/player/t4/server`
|
||||||
|
- `/home/player/t4/UI`
|
||||||
|
|
||||||
|
Дополнительно:
|
||||||
|
- подробная памятка на самом сервере: `/home/player/Agents.md`
|
||||||
|
|
||||||
|
## Порты и systemd
|
||||||
|
|
||||||
|
Соответствие инстансов:
|
||||||
|
- `t1` → localhost `7101` → `shine-t1.service`
|
||||||
|
- `t2` → localhost `7102` → `shine-t2.service`
|
||||||
|
- `t3` → localhost `7103` → `shine-t3.service`
|
||||||
|
- `t4` → localhost `7104` → `shine-t4.service`
|
||||||
|
|
||||||
|
Каждый unit запускает один и тот же jar:
|
||||||
|
- `/home/player/tX/server/shine-server.jar`
|
||||||
|
|
||||||
|
Рабочая директория каждого unit:
|
||||||
|
- `/home/player/tX/server`
|
||||||
|
|
||||||
|
Это важно, потому что сервер читает внешний `application.properties` именно из текущей рабочей директории.
|
||||||
|
|
||||||
|
## Конфиги сервера
|
||||||
|
|
||||||
|
У каждого инстанса свой файл:
|
||||||
|
- `/home/player/tX/server/application.properties`
|
||||||
|
|
||||||
|
Ключевые параметры в нём:
|
||||||
|
- `server.port=710X`
|
||||||
|
- `server.SHiNE.login=server_tX`
|
||||||
|
- `db.path=data/shine.sqlite`
|
||||||
|
- `solana.cluster=devnet`
|
||||||
|
- `solana.rpcUrl=https://api.devnet.solana.com`
|
||||||
|
- `server.ui.indexPath=/home/player/tX/UI/index.html`
|
||||||
|
- `server.info.url=https://tX.shineup.me`
|
||||||
|
- `server.info.origin=devnet`
|
||||||
|
|
||||||
|
Важно:
|
||||||
|
- Program ID SHiNE одинаковые для mainnet и devnet.
|
||||||
|
- Поэтому для перевода инстанса на devnet достаточно правильных `solana.cluster` и `solana.rpcUrl`.
|
||||||
|
|
||||||
|
## Конфиги UI
|
||||||
|
|
||||||
|
У каждого домена лежит отдельная копия `shine-UI`.
|
||||||
|
|
||||||
|
В каждой копии меняется `js/deploy-config.js`:
|
||||||
|
- `defaultServerLogin=server_tX`
|
||||||
|
- `defaultServerAddress=tX.shineup.me`
|
||||||
|
- `defaultSolanaCluster=devnet`
|
||||||
|
- `defaultSolanaEndpoint=https://api.devnet.solana.com`
|
||||||
|
|
||||||
|
За счёт этого:
|
||||||
|
- UI по умолчанию открывает именно свой сервер
|
||||||
|
- `server-ui` формы по умолчанию используют именно `devnet`
|
||||||
|
|
||||||
|
## Caddy
|
||||||
|
|
||||||
|
Конфиг:
|
||||||
|
- `/etc/caddy/Caddyfile`
|
||||||
|
|
||||||
|
Логика по каждому сайту одинаковая:
|
||||||
|
- статические файлы берутся из `/home/player/tX/UI`
|
||||||
|
- путь `/ws` проксируется на `127.0.0.1:710X`
|
||||||
|
|
||||||
|
Права доступа:
|
||||||
|
- каталог `/home/player` и `/home/player/tX` должен быть доступен на `+x` для чтения через Caddy
|
||||||
|
- все каталоги и файлы в `/home/player/tX/UI` должны быть читаемы пользователем `caddy`
|
||||||
|
|
||||||
|
## Что уже проверено
|
||||||
|
|
||||||
|
После настройки было подтверждено:
|
||||||
|
- `https://t1.shineup.me` отвечает `HTTP 200`
|
||||||
|
- `https://t2.shineup.me` отвечает `HTTP 200`
|
||||||
|
- `https://t3.shineup.me` отвечает `HTTP 200`
|
||||||
|
- `https://t4.shineup.me` отвечает `HTTP 200`
|
||||||
|
- `Caddy` успешно выпустил сертификаты Let's Encrypt на все 4 домена
|
||||||
|
- все 4 процесса Java слушают свои порты `7101..7104`
|
||||||
|
- в логах есть строка `WS сервер запущен на ws://localhost:710X/ws`
|
||||||
|
|
||||||
|
## Важный operational-нюанс
|
||||||
|
|
||||||
|
Официальный `https://api.devnet.solana.com` может отдавать `HTTP 429`, если несколько инстансов одновременно делают bootstrap PDA/sync-серверов на старте.
|
||||||
|
|
||||||
|
На практике это уже проявилось:
|
||||||
|
- `t3` и `t4` подтянули `sync_servers` сразу
|
||||||
|
- `t1` и `t2` на первом одновременном старте словили `429`
|
||||||
|
- после последовательного рестарта `shine-t1` и `shine-t2` они тоже успешно сохранили `sync_servers`
|
||||||
|
|
||||||
|
Если после очередного деплоя какой-то инстанс не подтянул `sync_servers`, сначала делать не массовый рестарт, а по одному:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart shine-t1
|
||||||
|
sleep 8
|
||||||
|
sudo systemctl restart shine-t2
|
||||||
|
sleep 8
|
||||||
|
sudo systemctl restart shine-t3
|
||||||
|
sleep 8
|
||||||
|
sudo systemctl restart shine-t4
|
||||||
|
```
|
||||||
|
|
||||||
|
## Как обновлять сервер
|
||||||
|
|
||||||
|
1. Локально собрать jar:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew shadowJar
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Залить `SHiNE-server/build/libs/shine-server.jar` в каждый нужный каталог:
|
||||||
|
- `/home/player/t1/server/shine-server.jar`
|
||||||
|
- `/home/player/t2/server/shine-server.jar`
|
||||||
|
- `/home/player/t3/server/shine-server.jar`
|
||||||
|
- `/home/player/t4/server/shine-server.jar`
|
||||||
|
|
||||||
|
3. Если менялся runtime-конфиг, обновить соответствующий `application.properties`.
|
||||||
|
|
||||||
|
4. Перезапускать сервисы лучше по одному, с паузой, чтобы снизить шанс `429` от devnet RPC.
|
||||||
|
|
||||||
|
## Как обновлять UI
|
||||||
|
|
||||||
|
1. Взять свежую локальную папку `shine-UI/`.
|
||||||
|
2. Для каждой копии подставить свой `deploy-config.js`.
|
||||||
|
3. Скопировать файлы в `/home/player/tX/UI/`.
|
||||||
|
4. Проверить права чтения для Caddy.
|
||||||
|
|
||||||
|
## Полезные команды на VPS
|
||||||
|
|
||||||
|
Проверка сервисов:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl --no-pager --full status caddy shine-t1 shine-t2 shine-t3 shine-t4
|
||||||
|
```
|
||||||
|
|
||||||
|
Перезапуск одного инстанса:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl restart shine-t1
|
||||||
|
```
|
||||||
|
|
||||||
|
Логи одного инстанса:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tail -n 200 /home/player/t1/server/logs/app.log
|
||||||
|
sudo journalctl -u shine-t1 -n 200 --no-pager
|
||||||
|
```
|
||||||
|
|
||||||
|
Проверка Caddy:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo caddy validate --config /etc/caddy/Caddyfile
|
||||||
|
curl -I https://t1.shineup.me
|
||||||
|
```
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Тестовый VPS с 4 SHiNE-серверами
|
||||||
|
|
||||||
|
В этой папке описан отдельный тестовый VPS `178.208.90.249`, на котором подняты 4 независимых SHiNE-инстанса под доменами `t1.shineup.me` ... `t4.shineup.me`.
|
||||||
|
|
||||||
|
Текущая основная схема:
|
||||||
|
- пользователь на VPS: `player`
|
||||||
|
- все 4 инстанса работают через `devnet`
|
||||||
|
- каждый инстанс имеет свой каталог `server`, свой каталог `UI`, свой `systemd` unit и свой localhost-порт
|
||||||
|
- внешний HTTPS и маршрутизацию `/ws` обслуживает один общий `Caddy`
|
||||||
|
|
||||||
|
Детальное описание:
|
||||||
|
- [178.208.90.249_quad_devnet.md](/home/ai/work/SHiNE/SHiNE-server-sha256/Dev_Docs/deploy/test-server/178.208.90.249_quad_devnet.md)
|
||||||
+15
-4
@@ -1,15 +1,18 @@
|
|||||||
package utils.config;
|
package utils.config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Публичные адреса Solana-программ SHiNE (жёстко зафиксированы для mainnet).
|
* Публичные адреса Solana-программ SHiNE.
|
||||||
* Секреты на сервере не хранятся.
|
* Program ID одинаковые для mainnet/devnet, а cluster/RPC должны
|
||||||
|
* переопределяться через application.properties конкретного инстанса.
|
||||||
*/
|
*/
|
||||||
public final class SolanaProgramsConfig {
|
public final class SolanaProgramsConfig {
|
||||||
|
|
||||||
private SolanaProgramsConfig() {}
|
private SolanaProgramsConfig() {}
|
||||||
|
|
||||||
public static final String SOLANA_CLUSTER = "mainnet-beta";
|
private static final AppConfig CONFIG = AppConfig.getInstance();
|
||||||
public static final String SOLANA_RPC_URL = "https://api.mainnet-beta.solana.com";
|
|
||||||
|
public static final String SOLANA_CLUSTER = getParam("solana.cluster", "mainnet-beta");
|
||||||
|
public static final String SOLANA_RPC_URL = getParam("solana.rpcUrl", "https://api.mainnet-beta.solana.com");
|
||||||
|
|
||||||
// Программа регистрации пользователей (shine_users), задеплоена в mainnet.
|
// Программа регистрации пользователей (shine_users), задеплоена в mainnet.
|
||||||
public static final String SHINE_USERS_PROGRAM_ID = "SHiNEPr1APdAgNBteUyBXcNovaHctpSjUu8oH2ZJdN6";
|
public static final String SHINE_USERS_PROGRAM_ID = "SHiNEPr1APdAgNBteUyBXcNovaHctpSjUu8oH2ZJdN6";
|
||||||
@@ -17,4 +20,12 @@ public final class SolanaProgramsConfig {
|
|||||||
// Отдельно фиксируем адреса связанной инфраструктуры, чтобы UI/сервер ссылались одинаково.
|
// Отдельно фиксируем адреса связанной инфраструктуры, чтобы UI/сервер ссылались одинаково.
|
||||||
public static final String SHINE_LOGIN_GUARD_PROGRAM_ID = "SHiGxGsXGioQYCYhchQ5R7KWoxN5UjFAFsucPf6sfnh";
|
public static final String SHINE_LOGIN_GUARD_PROGRAM_ID = "SHiGxGsXGioQYCYhchQ5R7KWoxN5UjFAFsucPf6sfnh";
|
||||||
public static final String SHINE_PAYMENTS_PROGRAM_ID = "SHiPmXbM9Fs9khzRUW3TGKsS2W84aqaXTxs3ZkajW9v";
|
public static final String SHINE_PAYMENTS_PROGRAM_ID = "SHiPmXbM9Fs9khzRUW3TGKsS2W84aqaXTxs3ZkajW9v";
|
||||||
|
|
||||||
|
private static String getParam(String key, String defaultValue) {
|
||||||
|
String value = CONFIG.getParam(key);
|
||||||
|
if (value == null || value.isBlank()) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
return value.trim();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
server.1port=7070
|
server.1port=7070
|
||||||
db.path=data/shine.sqlite
|
db.path=data/shine.sqlite
|
||||||
server.SHiNE.login=shineupme
|
server.SHiNE.login=shineupme
|
||||||
|
solana.cluster=mainnet-beta
|
||||||
|
solana.rpcUrl=https://api.mainnet-beta.solana.com
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
# Межсерверная синхронизация: как создавать локальную запись пользователя,
|
# Межсерверная синхронизация: как создавать локальную запись пользователя,
|
||||||
@@ -56,18 +58,12 @@ call.ice.turn.password=
|
|||||||
# Каждый блок описывает один TURN-узел. Новые узлы добавляются по индексу.
|
# Каждый блок описывает один TURN-узел. Новые узлы добавляются по индексу.
|
||||||
# Приоритет авторизации на узел: sharedSecret -> статические username/password.
|
# Приоритет авторизации на узел: sharedSecret -> статические username/password.
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
call.ice.turn.servers.1.id=promo-node-93
|
call.ice.turn.servers.1.id=shineup-main-185
|
||||||
call.ice.turn.servers.1.urls=turn:93.170.12.154:3478?transport=udp,turn:93.170.12.154:3478?transport=tcp
|
call.ice.turn.servers.1.urls=turn:185.229.109.118:3478?transport=udp,turn:185.229.109.118:3478?transport=tcp
|
||||||
call.ice.turn.servers.1.sharedSecret=def6d444734d380d2f67a9d345b1debf985eaba0973c343e392c060d97c30106
|
call.ice.turn.servers.1.sharedSecret=def6d444734d380d2f67a9d345b1debf985eaba0973c343e392c060d97c30106
|
||||||
call.ice.turn.servers.1.username=
|
call.ice.turn.servers.1.username=
|
||||||
call.ice.turn.servers.1.password=
|
call.ice.turn.servers.1.password=
|
||||||
|
|
||||||
call.ice.turn.servers.2.id=shineup-main-185
|
|
||||||
call.ice.turn.servers.2.urls=turn:185.229.109.118:3478?transport=udp,turn:185.229.109.118:3478?transport=tcp
|
|
||||||
call.ice.turn.servers.2.sharedSecret=def6d444734d380d2f67a9d345b1debf985eaba0973c343e392c060d97c30106
|
|
||||||
call.ice.turn.servers.2.username=
|
|
||||||
call.ice.turn.servers.2.password=
|
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
# Временные debug HTTP API для тестирования соединений
|
# Временные debug HTTP API для тестирования соединений
|
||||||
# true - endpoint'ы /debug/ws/* включены (только при наличии .debug-token)
|
# true - endpoint'ы /debug/ws/* включены (только при наличии .debug-token)
|
||||||
|
|||||||
+2
-2
@@ -1,2 +1,2 @@
|
|||||||
client.version=1.2.303
|
client.version=1.2.304
|
||||||
server.version=1.2.282
|
server.version=1.2.283
|
||||||
|
|||||||
@@ -5,3 +5,5 @@ export const defaultServerLogin = 'shineupme';
|
|||||||
export const defaultServerAddress = 'shineup.me';
|
export const defaultServerAddress = 'shineup.me';
|
||||||
export const defaultServerHttp = `https://${defaultServerAddress}`;
|
export const defaultServerHttp = `https://${defaultServerAddress}`;
|
||||||
export const defaultServerWs = `wss://${defaultServerAddress}/ws`;
|
export const defaultServerWs = `wss://${defaultServerAddress}/ws`;
|
||||||
|
export const defaultSolanaCluster = 'mainnet-beta';
|
||||||
|
export const defaultSolanaEndpoint = 'https://solana-rpc.publicnode.com';
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
export const SOLANA_CLUSTER = 'mainnet-beta';
|
import { defaultSolanaCluster, defaultSolanaEndpoint } from './deploy-config.js';
|
||||||
// Для браузерного UI используем endpoint, который не режет JSON-RPC по Origin.
|
|
||||||
export const SOLANA_ENDPOINT_DEFAULT = 'https://solana-rpc.publicnode.com';
|
export const SOLANA_CLUSTER = defaultSolanaCluster;
|
||||||
|
// Для браузерного UI endpoint выбирается на уровне deploy-config.js конкретного инстанса.
|
||||||
|
export const SOLANA_ENDPOINT_DEFAULT = defaultSolanaEndpoint;
|
||||||
|
|
||||||
// Единый файл актуальных Solana Program ID для UI-части SHiNE.
|
// Единый файл актуальных Solana Program ID для UI-части SHiNE.
|
||||||
// При смене адресов обновлять этот файл и все его потребители внутри shine-UI.
|
// При смене адресов обновлять этот файл и все его потребители внутри shine-UI.
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
validateLoginOrThrow,
|
validateLoginOrThrow,
|
||||||
wireDeviceAddressPreview,
|
wireDeviceAddressPreview,
|
||||||
} from './server-ui-shared.js';
|
} from './server-ui-shared.js';
|
||||||
import { defaultServerAddress, defaultServerLogin } from '../../js/deploy-config.js';
|
import { defaultServerAddress, defaultServerLogin, defaultSolanaEndpoint } from '../../js/deploy-config.js';
|
||||||
|
|
||||||
const fieldMap = {
|
const fieldMap = {
|
||||||
masterSecret: 'masterSecret',
|
masterSecret: 'masterSecret',
|
||||||
@@ -37,6 +37,7 @@ wireDeviceAddressPreview(fieldMap);
|
|||||||
$('password').value = '';
|
$('password').value = '';
|
||||||
$('login').placeholder = defaultServerLogin;
|
$('login').placeholder = defaultServerLogin;
|
||||||
$('serverAddress').placeholder = defaultServerAddress;
|
$('serverAddress').placeholder = defaultServerAddress;
|
||||||
|
$('endpoint').value = defaultSolanaEndpoint;
|
||||||
|
|
||||||
$('btnTopupDevnet').addEventListener('click', () => {
|
$('btnTopupDevnet').addEventListener('click', () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { readShineUserPdaByRef } from '../../js/services/shine-user-pda-service.js';
|
import { readShineUserPdaByRef } from '../../js/services/shine-user-pda-service.js';
|
||||||
import { bytesToBase58 } from '../../js/services/crypto-utils.js';
|
import { bytesToBase58 } from '../../js/services/crypto-utils.js';
|
||||||
import { $, clearStatus, formatBigInt, formatTimestamp, setStatus } from './server-ui-shared.js';
|
import { $, clearStatus, formatBigInt, formatTimestamp, setStatus } from './server-ui-shared.js';
|
||||||
|
import { defaultSolanaEndpoint } from '../../js/deploy-config.js';
|
||||||
|
|
||||||
function hex(bytes) {
|
function hex(bytes) {
|
||||||
const data = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes || []);
|
const data = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes || []);
|
||||||
@@ -12,6 +13,10 @@ function base58(bytes) {
|
|||||||
return bytesToBase58(data);
|
return bytesToBase58(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($('endpoint')) {
|
||||||
|
$('endpoint').value = defaultSolanaEndpoint;
|
||||||
|
}
|
||||||
|
|
||||||
function renderRows(rows) {
|
function renderRows(rows) {
|
||||||
const container = $('summaryRows');
|
const container = $('summaryRows');
|
||||||
container.innerHTML = '';
|
container.innerHTML = '';
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import {
|
|||||||
validateLoginOrThrow,
|
validateLoginOrThrow,
|
||||||
wireDeviceAddressPreview,
|
wireDeviceAddressPreview,
|
||||||
} from './server-ui-shared.js';
|
} from './server-ui-shared.js';
|
||||||
import { defaultServerAddress, defaultServerLogin } from '../../js/deploy-config.js';
|
import { defaultServerAddress, defaultServerLogin, defaultSolanaEndpoint } from '../../js/deploy-config.js';
|
||||||
|
|
||||||
const fieldMap = {
|
const fieldMap = {
|
||||||
masterSecret: 'masterSecret',
|
masterSecret: 'masterSecret',
|
||||||
@@ -100,6 +100,7 @@ wireDeviceAddressPreview(fieldMap);
|
|||||||
$('password').value = '';
|
$('password').value = '';
|
||||||
$('login').placeholder = defaultServerLogin;
|
$('login').placeholder = defaultServerLogin;
|
||||||
$('serverAddress').placeholder = defaultServerAddress;
|
$('serverAddress').placeholder = defaultServerAddress;
|
||||||
|
$('endpoint').value = defaultSolanaEndpoint;
|
||||||
resetExpectedKeysUi();
|
resetExpectedKeysUi();
|
||||||
|
|
||||||
$('btnTopupDevnet').addEventListener('click', () => {
|
$('btnTopupDevnet').addEventListener('click', () => {
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"createdAt": "2026-07-08T11:10:08.590Z",
|
||||||
|
"cluster": "mainnet-beta",
|
||||||
|
"realmName": "SHiNE DAO",
|
||||||
|
"governanceProgramId": "GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw",
|
||||||
|
"issuer": "SHiJ58FvbJQJnPEUa5mZNVpWd1ym9CkjjPgeHYzUJmh",
|
||||||
|
"governingMint": "SHi1KQ9BdJTmzwy5aPJQs8QB4er4Ka8HaJTQcyE4gY1",
|
||||||
|
"realm": "FcMg5G3RpAYvW3vvztrcMuFXifWYR3HYiTuPfVgwuN4K",
|
||||||
|
"governance": "9EEcpw6JK74CqMAsQ46LUhKu7AqX274TDuaAdoDwpbBh",
|
||||||
|
"mintAuthorityBefore": "SHiJ58FvbJQJnPEUa5mZNVpWd1ym9CkjjPgeHYzUJmh",
|
||||||
|
"freezeAuthorityBefore": "SHiJ58FvbJQJnPEUa5mZNVpWd1ym9CkjjPgeHYzUJmh",
|
||||||
|
"metadataUpdateAuthorityBefore": "SHiJ58FvbJQJnPEUa5mZNVpWd1ym9CkjjPgeHYzUJmh",
|
||||||
|
"realmAuthorityBefore": "SHiJ58FvbJQJnPEUa5mZNVpWd1ym9CkjjPgeHYzUJmh",
|
||||||
|
"mintAuthorityAfter": "9EEcpw6JK74CqMAsQ46LUhKu7AqX274TDuaAdoDwpbBh",
|
||||||
|
"freezeAuthorityAfter": "9EEcpw6JK74CqMAsQ46LUhKu7AqX274TDuaAdoDwpbBh",
|
||||||
|
"realmAuthorityAfter": "9EEcpw6JK74CqMAsQ46LUhKu7AqX274TDuaAdoDwpbBh",
|
||||||
|
"metadataUpdateAuthorityAfter": "SHiJ58FvbJQJnPEUa5mZNVpWd1ym9CkjjPgeHYzUJmh",
|
||||||
|
"txTransferAuthorities": "4QrYB8xne3MSrPjJiUBFy2xrukmyV18qBzSmcWaBr3LRdbUetxbgdYJvbw18mjgweLYKML39VpGTMhJW2GMZqsfi",
|
||||||
|
"txSetRealmAuthority": "5GgbwX7YYveKumXpFDBytJbfsqiPhhzvFaxNaByqYbXtP8WNgjw24uWvYPTGp2gCukhdMbLyXi3nieyNrAwuz1V6",
|
||||||
|
"txSetMetadataUpdateAuthority": "a3wNDpx743sTZB2ckH2w6yIuj3uW7aivTIR2OSwUgFkv8jYvmhaH4rV0KuHU5/gPzTJOyDBDOyiUaqXcDfGKCw=="
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user