# Развёртывание Flamy Trade Документ описывает production-развёртывание сайта `trade.flamy.studio` без ML-runtime и без будущего API. Эти части подключаются отдельно. ## Схема ```text Internet -> Router :80/:443 -> edge-proxy VM / Caddy -> 10.20.0.20:18082 -> flamy_trade_nginx -> flamy_trade_app:3000 ``` На VM публикуется только nginx. Node-приложение доступно только во внутренней Docker-сети. ## Переменные Скопируйте `.env.example` в `.env` на сервере и проверьте значения: ```bash PUBLIC_SITE_URL=https://trade.flamy.studio PUBLIC_SITE_NAME=Flamy Trade PUBLIC_SITE_DESCRIPTION=Публичная витрина ML-прогнозов для крипторынка. HOST=0.0.0.0 PORT=3000 ORIGIN=https://trade.flamy.studio BODY_SIZE_LIMIT=1M SHUTDOWN_TIMEOUT=15 APP_HOST_IP=10.20.0.20 APP_PUBLISHED_PORT=18082 APP_IMAGE_TAG= ``` Перед фиксацией порта проверьте, что `18082` свободен: ```bash sudo ss -lntup | grep ':18082' docker ps --format 'table {{.Names}}\t{{.Ports}}' ``` ## Сборка ```bash pnpm install --frozen-lockfile pnpm format:check pnpm lint pnpm check pnpm build pnpm audit ``` `pnpm outdated` должен проверяться вручную. На текущем стеке допустимы только осознанные удержания: `@types/node` на ветке 24 под Node 24 LTS и TypeScript 6.x до обновления peer constraints в SvelteKit/typescript-eslint. Docker: ```bash docker compose config docker compose build --pull docker compose up -d --wait docker compose ps docker compose logs --tail=200 ``` ## Caddy Блок для edge-proxy: ```caddyfile trade.flamy.studio { encode zstd gzip reverse_proxy 10.20.0.20:18082 { header_up Host {host} header_up X-Real-IP {remote_host} } } ``` Перед reload: ```bash sudo cp -a /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak.$(date +%F_%H%M%S) sudo caddy validate --config /etc/caddy/Caddyfile sudo systemctl reload caddy ``` ## Smoke-check С docker-runtime: ```bash curl -fsS http://10.20.0.20:18082/healthz curl -I http://10.20.0.20:18082/ ``` Снаружи: ```bash curl -I http://trade.flamy.studio curl -I https://trade.flamy.studio curl -fsS https://trade.flamy.studio/healthz ``` Маршруты: ```text / 200 /about 200 /blog 200 /blog/osnovy-upravleniya-riskami 200 /dashboard 200 /healthz 200 /favicon.svg 200 /robots.txt 200 /sitemap.xml 200 /nesuschestvuyuschiy-url 404 ``` ## Rollback 1. Каждый image получает тег git SHA через `APP_IMAGE_TAG`. 2. Предыдущий image не удаляется до успешного smoke-check. 3. Для отката поменяйте `APP_IMAGE_TAG` на предыдущий SHA. 4. Выполните: ```bash docker compose up -d --no-build ``` Если проблема в маршрутизации, восстановите backup Caddyfile и выполните `sudo systemctl reload caddy`.