Сквозная миграция HY2XS на современную Hysteria (2.12.2) и переход на v1. Build: - версия Hysteria резолвится на этапе сборки из HyNetworks/hysteria и замораживается в metadata пакета (version + immutable url + sha256); - compatibility gate: реальный бинарник должен принять канонический конфиг HY2XS для gecko и salamander до создания пакета; - сборка прогоняет тесты оркестратора и админки. Конфигурационный контракт: - HY2XS_CONFIG_SCHEMA_VERSION=2, чужая схема отклоняется fail-fast; - obfs стал настоящим union gecko|salamander, gecko — default; - obfs-блок рендерится оркестратором целиком, два подтипа одновременно структурно невозможны; - современный baseline: congestion bbr/standard, disableLossCompensation=false, disableStatelessReset=false, полный quic-блок. Исправления: - share URI для gecko: генератор был завязан на Obfs.Salamander.Password и выдавал нерабочую ссылку при любой другой обфускации; - SNI брался только из ACME-блока и уходил пустым при HY2XS_TLS_MODE=file; - экспорт конфига выносил trafficStats.secret, access_token и obfs-пароль; - экспорт терял неизвестные upstream-поля при round-trip через типизированную модель; - renderRuntimeEnv печатал тип обфускации литералом, расходясь с конфигом; - namedotcom удалён из ACME-реестра (нет в Hysteria с 2.11.0). Тесты: - 95 тестов оркестратора: env, рендер, семантика профиля, резолвер, rollover; - тесты URI и экспорта в Go; - tools/test/e2e-hysteria.sh с реальным клиентом Hysteria. UX: - подсказки и примеры в форме создания пира. Прочее: CHANGELOG.md, .gitattributes (LF для target-side файлов), документация на русском.
13 KiB
HY2XS production builder
Этот каталог содержит production builder для HY2XS.
Builder собирает один переносимый install-archive:
dist/hy2xs-install-<version>.tar.gz
Этот архив переносится на production server, распаковывается и устанавливается через install.sh.
На production server не должно быть сборки из исходников: без go build, без bun install, без pnpm install, без frontend build и без TypeScript transpilation.
Что где лежит
Основные части проекта:
tools/build/build.sh— главный entrypoint сборки.tools/build/lib/deps.sh— проверка Debian/amd64, установка build dependencies, установка Go/Bun/Node.js/pnpm.tools/build/lib/package.sh— сборка orchestrator, сборка HY2XS admin, создание stage directory и tar.gz архива.tools/build/lib/verify.sh— проверка структуры репозитория и итогового архива.tools/build/lib/acceptance.sh— acceptance-проверки production-контракта.tools/build/lib/hysteria.sh— разрешение upstream-версии Hysteria и compatibility gate.tools/build/hysteria-lock.env— fallback-значения для офлайн-сборки (HYSTERIA_CHANNEL=pinned).tools/test/e2e-hysteria.sh— end-to-end проверка с реальным клиентом Hysteria.orchestrator— TypeScript/Bun install-only orchestrator.apps— HY2XS admin: Go backend и Vue frontend.package— skeleton будущего install package:install.sh, templates, systemd units, default config.dist— итоговые архивы. Создаётся builder'ом, в git обычно не хранится..toolchain— локальный toolchain builder'а. Создаётся автоматически, в git не хранится.
Требования к build machine
Production build поддерживается только на:
- Debian 13;
- amd64 / x86_64;
- root или пользователь с
sudo; - доступ в интернет.
Нужен outbound HTTPS/DNS до:
- Debian apt repositories;
go.dev;github.com;nodejs.org;- npm registry.
Windows и macOS можно использовать для редактирования исходников, но финальную production-сборку надо делать на Debian 13 amd64.
Что builder делает сам
При запуске builder:
- Проверяет, что host — Debian 13 amd64.
- Проверяет структуру репозитория.
- Устанавливает недостающие системные build dependencies через
apt-get. - Проверяет или скачивает локальные версии:
- Go
1.21.13; - Bun
1.3.13; - Node.js
20.19.0; - pnpm
9.15.9.
- Go
- Прогоняет тесты и типы оркестратора (
bun test,tsc --noEmit). - Разрешает upstream-версию Hysteria, скачивает артефакт и считает SHA-256.
- Проходит compatibility gate: реальный бинарник Hysteria должен принять канонический конфиг HY2XS.
- Копирует package skeleton.
- Собирает install-only orchestrator в standalone binary.
- Собирает frontend и backend HY2XS admin в Linux amd64 binary.
- Прогоняет
go vetиgo testдля HY2XS admin (после сборки frontend, потому чтоgo:embed all:distтребует готовых ассетов). - Записывает metadata и checksums.
- Создаёт
dist/hy2xs-install-<version>.tar.gz. - Проверяет архив и прогоняет acceptance-проверки.
Версия Hysteria: разрешение и compatibility gate
Builder не хранит версию Hysteria вручную. По умолчанию он определяет последнюю стабильную версию сам и замораживает её в пакете.
Правила разрешения:
- канонический upstream —
HyNetworks/hysteria; - принимаются только стабильные релизы, без draft и prerelease;
- тег должен иметь вид
app/vX.Y.Z; - берётся ровно один артефакт
hysteria-linux-amd64; - URL используется в том виде, в каком его вернул upstream API, без пересборки строки;
- SHA-256 считается локально от скачанного файла;
- разрешённые значения попадают в metadata пакета.
Сравнение версий числовое, поэтому v2.9.10 считается новее v2.9.2.
После разрешения обязателен compatibility gate:
скачать бинарник
↓
сверить SHA-256 и `hysteria version`
↓
отрендерить канонический конфиг HY2XS тем же кодом, что и на target
↓
запустить настоящий Hysteria с этим конфигом (gecko и salamander)
↓
только после этого собирать release package
При несовместимости сборка останавливается:
BUILD FAILED: unsupported Hysteria stable v2.13.0
Это осознанное решение: ошибка должна проявиться на build machine, а не на production-сервере.
Переменные:
| Переменная | По умолчанию | Назначение |
|---|---|---|
HYSTERIA_CHANNEL |
stable |
stable — разрешить последнюю стабильную через upstream API; pinned — офлайн-сборка по hysteria-lock.env |
HYSTERIA_VERSION_OVERRIDE |
пусто | Закрепить конкретную версию vX.Y.Z |
HYSTERIA_COMPAT_GATE |
true |
Compatibility gate; для release-сборок обязателен |
HYSTERIA_WRITE_LOCK |
false |
Записать разрешённые значения обратно в hysteria-lock.env |
HYSTERIA_GATE_PORT |
34443 |
UDP-порт для временного запуска Hysteria в gate |
HYSTERIA_GATE_STATS_PORT |
34712 |
TCP-порт trafficStats в gate |
GITHUB_TOKEN |
пусто | Опционально: снимает anonymous rate limit GitHub API |
SKIP_TESTS |
false |
Аварийное отключение тестов; для release-сборок недопустимо |
Обновить lock-файл под текущий upstream:
HYSTERIA_WRITE_LOCK=true ./tools/build/build.sh
Важное про Bun и старые CPU
Bun имеет два Linux x64 artifact'а:
bun-linux-x64— обычный build;bun-linux-x64-baseline— build для CPU без AVX2.
Если CPU не поддерживает AVX2, обычный Bun может падать с Illegal instruction.
Builder автоматически проверяет /proc/cpuinfo.
По умолчанию:
BUN_FLAVOR=auto
Логика:
- если CPU поддерживает AVX2, используется
bun-linux-x64; - если CPU не поддерживает AVX2, используется
bun-linux-x64-baseline.
Можно принудительно задать flavor:
BUN_FLAVOR=x64 ./tools/build/build.sh
или:
BUN_FLAVOR=x64-baseline ./tools/build/build.sh
Запуск
Из корня репозитория:
./tools/build/build.sh
С явной версией и build id:
PACKAGE_VERSION=1.0.0 \
BUILD_ID=prod-$(date -u +%Y%m%dT%H%M%SZ) \
./tools/build/build.sh
Проверка результата
Проверка архива:
ls -lh dist/hy2xs-install-1.0.0.tar.gz
sha256sum dist/hy2xs-install-1.0.0.tar.gz | tee dist/hy2xs-install-1.0.0.tar.gz.sha256
Проверка обязательных файлов:
tar -tzf dist/hy2xs-install-1.0.0.tar.gz | grep -E '^(hy2xs-install/install.sh|hy2xs-install/orchestrator/hy2xs-orchestrator|hy2xs-install/ui/hy2xs-admin/hy2xs-admin|hy2xs-install/metadata/checksums.txt)$'
Проверка metadata:
tar -xOzf dist/hy2xs-install-1.0.0.tar.gz hy2xs-install/metadata/package.env
Когда обновлять orchestrator/bun.lock
Не перегенерируйте orchestrator/bun.lock во время production-сборки.
Обновлять и коммитить orchestrator/bun.lock следует только когда:
- изменился
orchestrator/package.json; - изменился
BUN_REQUIREDвtools/build/lib/deps.sh; - зависимости оркестратора обновляются осознанно.
Production builder всегда выполняет:
bun install --frozen-lockfile
Если команда падает, исправьте и закоммитьте lockfile в системе контроля версий. Не убирайте --frozen-lockfile.
Дисциплина lockfile для frontend
Не перегенерируйте frontend lock data во время обычной production-сборки.
Правила управления пакетами frontend:
apps/frontend/package.jsonобъявляет"packageManager": "pnpm@9.15.9";- builder использует закреплённый pnpm
9.15.9изPNPM_REQUIRED; - production-путь установки frontend всегда:
pnpm install --frozen-lockfile
Если frozen install падает, обновите зависимости осознанно в системе контроля версий и закоммитьте изменения lockfile. Не убирайте --frozen-lockfile из сборочного потока.
Полезные переменные
PACKAGE_VERSION=1.0.0BUILD_ID=prod-$(date -u +%Y%m%dT%H%M%SZ)BUN_FLAVOR=auto|x64|x64-baselineFRONTEND_NODE_OLD_SPACE_SIZE=2048(default memory limit for frontend build step)TOOLCHAIN_DIR=/custom/path/.toolchainVERIFY_TOOLCHAIN_CHECKSUMS=true
По умолчанию VERIFY_TOOLCHAIN_CHECKSUMS=true в tools/build/lib/deps.sh, поэтому для production-сборки обязательно передавать контрольные суммы:
GO_ARCHIVE_SHA256=<sha256>NODE_ARCHIVE_SHA256=<sha256>BUN_ARCHIVE_SHA256=<sha256>
Политика памяти при сборке frontend
Builder задаёт безопасный лимит heap для Node.js внутри bundle_ui():
--max-old-space-size=2048
Способы переопределения:
- изменить значение по умолчанию для этой политики:
FRONTEND_NODE_OLD_SPACE_SIZE=3072 ./tools/build/build.sh
- или передать полный набор собственных Node-опций (если
--max-old-space-sizeтам уже задан, builder не добавит второй):
NODE_OPTIONS="--max-old-space-size=3072" ./tools/build/build.sh
Диагностика
Проверить AVX2:
grep -m1 '^flags' /proc/cpuinfo | grep -qw avx2 && echo 'CPU has AVX2' || echo 'CPU has NO AVX2; Bun baseline is required'
Проверить Bun:
.toolchain/bun/bin/bun --version
echo "bun_exit=$?"
Если есть Illegal instruction, удалите старый Bun и пересоберите:
rm -rf .toolchain/bun .toolchain/bun-tmp
rm -f .toolchain/downloads/bun-linux-x64-*.zip
rm -f .toolchain/downloads/bun-linux-x64-baseline-*.zip
PACKAGE_VERSION=1.0.0 ./tools/build/build.sh
Проверить shell syntax:
bash -n tools/build/build.sh
bash -n tools/build/lib/common.sh
bash -n tools/build/lib/deps.sh
bash -n tools/build/lib/package.sh
bash -n tools/build/lib/verify.sh