chore: prepare production deployment

This commit is contained in:
2026-07-20 05:24:12 +05:00
parent 2e3550a4dc
commit 77ed2d8423
31 changed files with 681 additions and 496 deletions
+32 -51
View File
@@ -1,6 +1,6 @@
# Flamy Trade
Публичный frontend для `trade.flamy.studio`: лендинг, блог и демонстрационный дашборд ML-прогнозов по крипторынку.
Публичный frontend для `trade.flamy.studio`: лендинг, блог и исследовательский дашборд ML-прогнозов по крипторынку.
Проект построен на SvelteKit, Svelte 5 Runes, Tailwind CSS v4, TypeScript и `lightweight-charts`.
@@ -38,94 +38,75 @@ pnpm preview # preview production build
pnpm audit # аудит зависимостей
```
`pnpm outdated` может показывать `@types/node` 26.x и TypeScript 7.x. Это не ошибка текущего стека: проект закреплён на Node 24 LTS, а `@sveltejs/kit` и `typescript-eslint` на текущих версиях требуют TypeScript `<6.1`.
`prepare` намеренно выполняет `svelte-kit sync` без подавления ошибок. Если синхронизация SvelteKit падает, установка зависимостей тоже должна завершаться ошибкой.
## Конфигурация
Основные изменяемые значения вынесены в `.env.example`.
`.env.example` описывает production-настройки. Для сервера скопируйте его в `.env` и заполните значения без локальных заглушек.
Публичные значения сайта:
Основные переменные:
```bash
PUBLIC_SITE_URL=https://trade.flamy.studio
PUBLIC_SITE_NAME=Flamy Trade
PUBLIC_SITE_DESCRIPTION=Публичная витрина ML-прогнозов для крипторынка.
```
PUBLIC_DASHBOARD_DATA_MODE=research-static
Runtime-переменные SvelteKit adapter-node:
```bash
HOST=0.0.0.0
PORT=3000
ORIGIN=https://trade.flamy.studio
BODY_SIZE_LIMIT=1M
SHUTDOWN_TIMEOUT=15
```
APP_STOP_GRACE_PERIOD=20s
Docker Compose:
APP_IMAGE_REPOSITORY=registry.example.com/flamy-trade
APP_IMAGE_TAG=<git-sha>
BUILD_DATE=<utc-iso-date>
VCS_REF=<git-sha>
```bash
APP_HOST_IP=10.20.0.20
APP_PUBLISHED_PORT=18082
APP_IMAGE_TAG=<git-sha>
NGINX_IMAGE=nginxinc/nginx-unprivileged:1.30.4-alpine-perl@sha256:36fa38fb8f34faba45e7e1857644d6561f2faf45e7ce6b15e97d1a2a1682a0cd
```
`PUBLIC_DASHBOARD_DATA_MODE=research-static` означает, что дашборд показывает исследовательские синтетические данные. Это production-поведение текущего публичного этапа, а не интеграция с реальным торговым API.
## Структура
```text
src/lib/blog/posts.ts # статические статьи блога
src/lib/config/site.ts # единая конфигурация сайта и canonical URL
src/lib/stores/chartStore.ts # типы графика и демонстрационный provider
src/lib/components/Chart.svelte # lightweight-charts компонент
src/routes/healthz/+server.ts # health endpoint
src/routes/sitemap.xml/+server.ts # sitemap
docker/nginx/default.conf # project nginx
docs/deployment.md # runbook развёртывания
src/lib/blog/posts.ts # типизированные статьи блога
src/lib/config/site.ts # единая конфигурация сайта, canonical и metadata
src/lib/data/dashboard.ts # provider данных дашборда
src/lib/stores/chartStore.ts # типы графика и research-static генератор
src/lib/components/Chart.svelte # компонент lightweight-charts
src/routes/healthz/+server.ts # health endpoint
src/routes/robots.txt/+server.ts # runtime robots.txt
src/routes/sitemap.xml/+server.ts # runtime sitemap
docker/nginx/default.conf # nginx server config
docker/nginx/includes # общие nginx include-файлы
docs/deployment.md # runbook развёртывания
```
## Данные дашборда
Текущий provider в `chartStore.ts` генерирует демонстрационные данные. Он не является реальным торговым API и не меняет контракт будущего backend.
Ожидаемая форма `ChartData`:
```typescript
type ChartData = {
candles: Array<{ time: number; open: number; high: number; low: number; close: number }>;
prediction: Array<{ time: number; value: number }>;
signal: {
direction: 'long' | 'short';
confidence: number;
entry: number;
tp: number;
sl: number;
};
currentPrice: number;
change24h: number;
change24hPct: number;
};
```
## Блог
Статьи хранятся как типизированные блоки, а не как HTML-строки. Это позволяет рендерить контент без `{@html}` и без отдельной санитаризации.
## Production
Production-сборка рассчитана на схему:
Production-схема:
```text
Internet -> Caddy -> 10.20.0.20:18082 -> nginx -> app:3000
```
Публикуется только nginx. Node-приложение доступно только во внутренней Docker-сети. Nginx запускается через unprivileged image с `cap_drop: ALL`, `read_only` и `no-new-privileges`.
Подробный порядок развёртывания, Caddy block, smoke-check и rollback описаны в [docs/deployment.md](docs/deployment.md).
## Зависимости
Renovate закрепляет версии и digest Docker-образов, а также ждёт 3 дня перед обновлением свежих релизов. TypeScript 6.x является осознанным compatibility hold до обновления peer constraints в SvelteKit/typescript-eslint.
## Что не входит в текущий этап
Пока не подключаются:
- ML-runtime;
- реальный API;
- реальный торговый API;
- S3;
- база данных;
- Redis;