# OmniRoute Fly.io Deployment Guide (Русский) 🌐 **Languages:** 🇺🇸 [English](../../../../ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇪🇹 [am](../../../am/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇦 [ar](../../../ar/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇦🇿 [az](../../../az/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇬 [bg](../../../bg/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇩 [bn](../../../bn/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇦 [bs](../../../bs/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇨🇿 [cs](../../../cs/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇩🇰 [da](../../../da/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇩🇪 [de](../../../de/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇬🇷 [el](../../../el/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇪🇸 [es](../../../es/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇪🇪 [et](../../../et/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇷 [fa](../../../fa/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇫🇮 [fi](../../../fi/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇫🇷 [fr](../../../fr/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇪 [ga](../../../ga/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [gu](../../../gu/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇬 [ha](../../../ha/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇱 [he](../../../he/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [hi](../../../hi/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇭🇷 [hr](../../../hr/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇭🇺 [hu](../../../hu/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇦🇲 [hy](../../../hy/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇩 [id](../../../id/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇬 [ig](../../../ig/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇹 [it](../../../it/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇯🇵 [ja](../../../ja/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇬🇪 [ka](../../../ka/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇰🇭 [km](../../../km/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [kn](../../../kn/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇰🇷 [ko](../../../ko/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇱🇹 [lt](../../../lt/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇱🇻 [lv](../../../lv/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [ml](../../../ml/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [mr](../../../mr/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇲🇾 [ms](../../../ms/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇲🇹 [mt](../../../mt/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇲🇲 [my](../../../my/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇵 [ne](../../../ne/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇱 [nl](../../../nl/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇴 [no](../../../no/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [or](../../../or/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [pa](../../../pa/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇭 [phi](../../../phi/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇱 [pl](../../../pl/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇹 [pt](../../../pt/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇷 [pt-BR](../../../pt-BR/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇷🇴 [ro](../../../ro/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇱🇰 [si](../../../si/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇰 [sk](../../../sk/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇮 [sl](../../../sl/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇷🇸 [sr](../../../sr/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇪 [sv](../../../sv/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇰🇪 [sw](../../../sw/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [ta](../../../ta/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [te](../../../te/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇹🇭 [th](../../../th/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇹🇷 [tr](../../../tr/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇺🇦 [uk-UA](../../../uk-UA/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇰 [ur](../../../ur/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇺🇿 [uz](../../../uz/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇻🇳 [vi](../../../vi/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇬 [yo](../../../yo/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇨🇳 [zh-CN](../../../zh-CN/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇹🇼 [zh-TW](../../../zh-TW/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md) --- В этом документе описан фактический процесс развертывания OmniRoute на Fly.io для следующих сценариев: - Первое развертывание текущего проекта на Fly.io - Публикация последующих обновлений кода - Развертывание новых проектов по тому же рабочему процессу Это руководство основано на проверенной рабочей конфигурации текущего проекта. Имя приложения — `omniroute`. --- ## 1. Цели развертывания - Платформа: Fly.io - Метод развертывания: прямая локальная публикация с помощью `flyctl` - Среда выполнения: использование существующих `Dockerfile` и `fly.toml` в репозитории - Постоянное хранение данных: Fly Volume, подключенный к `/data` - URL-адрес доступа: `https://omniroute.fly.dev/` --- ## 2. Основная конфигурация текущего проекта Подтверждено, что файл `fly.toml` в текущем репозитории содержит следующие ключевые параметры: ```toml app = 'omniroute' primary_region = 'sin' [[mounts]] source = 'data' destination = '/data' [processes] app = 'node run-standalone.mjs' [http_service] internal_port = 20128 [env] TZ = "Asia/Shanghai" HOST = "0.0.0.0" HOSTNAME = "0.0.0.0" BIND = "0.0.0.0" ``` Примечания: - `app = 'omniroute'` определяет, в какое приложение Fly выполняется развертывание - `destination = '/data'` определяет каталог подключения постоянного тома - Для этого проекта необходимо задать `DATA_DIR=/data`, иначе база данных и ключи будут записываться во временный каталог контейнера --- ## 3. Предварительные требования ### 3.1 Установка Fly CLI Windows PowerShell: ```powershell pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex" ``` Если сценарий установки завершается с ошибкой в вашей среде, вы также можете вручную загрузить исполняемый файл `flyctl` и добавить его в `PATH`. ### 3.2 Вход в учетную запись Fly ```powershell flyctl auth login ``` ### 3.3 Проверка состояния входа ```powershell flyctl auth whoami flyctl version ``` --- ## 4. Первое развертывание текущего проекта ### 4.1 Клонирование кода и переход в каталог ```powershell git clone https://github.com/diegosouzapw/OmniRoute.git cd OmniRoute ``` ### 4.2 Проверка имени приложения Откройте `fly.toml` и проверьте следующую строку: ```toml app = 'omniroute' ``` Если вы выполняете развертывание в собственное новое приложение, можно изменить его имя на глобально уникальное, например: ```toml app = 'omniroute-yourname' ``` Примечание: - Убедитесь, что приложение, отображаемое в консоли, соответствует значению `app` в `fly.toml` - Если ранее вы использовали другое имя, например `oroute`, не путайте его с `omniroute` ### 4.3 Создание приложения Если приложение еще не существует: ```powershell flyctl apps create omniroute ``` Если вы изменили имя приложения, замените `omniroute` выбранным именем. ### 4.4 Первое развертывание ```powershell flyctl deploy ``` --- ## 5. Обязательные параметры Для этого проекта рекомендуется настроить на Fly.io как минимум следующие параметры. ### 5.1 Проверенные параметры Эти параметры использовались при фактических развертываниях текущего приложения `omniroute`: - `API_KEY_SECRET` - `DATA_DIR` - `JWT_SECRET` - `MACHINE_ID_SALT` - `NEXT_PUBLIC_BASE_URL` - `OMNIROUTE_WS_BRIDGE_SECRET` (обязателен в производственной среде — используется для аутентификации моста WebSocket) - `STORAGE_ENCRYPTION_KEY` ### 5.2 О параметре `INITIAL_PASSWORD` В текущем проекте параметр `INITIAL_PASSWORD` не задан, поскольку для этого развертывания он не требуется. Если он не задан: - В журнале запуска будет указано, что пароль по умолчанию — `CHANGEME` - После развертывания следует как можно скорее изменить пароль для входа в настройках системы Если вы хотите автоматически инициализировать пароль бэкенда, его можно добавить позже: - `INITIAL_PASSWORD` --- ## 6. Рекомендуемые параметры ### 6.1 Настройка секретов Для Fly Secrets рекомендуется использовать следующие переменные: | Переменная | Рекомендация | Описание | | ---------------------------- | --------------------------- | ------------------------------------------------------------- | | `API_KEY_SECRET` | Обязательно | Используется для генерации и проверки ключей API | | `JWT_SECRET` | Обязательно | Используется для сеансов входа и подписания JWT | | `OMNIROUTE_WS_BRIDGE_SECRET` | Обязательно в рабочей среде | Секрет аутентификации моста WebSocket | | `STORAGE_ENCRYPTION_KEY` | Настоятельно рекомендуется | Шифрует конфиденциальные сведения о подключениях при хранении | | `MACHINE_ID_SALT` | Рекомендуется | Генерирует стабильный идентификатор машины | | `INITIAL_PASSWORD` | Необязательно | Задаёт начальный пароль бэкенда при первом развёртывании | | Закрытые данные OAuth/API | По необходимости | Конфигурация аутентификации на внешних платформах | ### 6.2 Рекомендуемые значения для текущего проекта | Переменная | Рекомендуемое значение | | ---------------------- | --------------------------- | | `DATA_DIR` | `/data` | | `NEXT_PUBLIC_BASE_URL` | `https://omniroute.fly.dev` | Примечания: - `DATA_DIR=/data` имеет критически важное значение и должен соответствовать точке монтирования Fly Volume - `NEXT_PUBLIC_BASE_URL` используется планировщиком, обратными вызовами фронтенда и в аналогичных сценариях ### 6.3 Настройка URL-адреса обратного вызова OAuth Если вам необходимо включить провайдеров на основе OAuth (например, Antigravity, Gemini, Cursor) в развёртывании Fly.io, убедитесь в выполнении следующих двух условий: 1. **Задайте для `NEXT_PUBLIC_BASE_URL` ваш общедоступный HTTPS-домен** ```powershell flyctl secrets set NEXT_PUBLIC_BASE_URL=https://omniroute.fly.dev -a omniroute ``` Если вы используете пользовательский домен, замените его соответствующим доменом (например, `https://omniroute.yourdomain.com`). 2. **Настройте URL-адрес обратного вызова в консоли провайдера** Все провайдеры OAuth используют единый путь обратного вызова `/callback` — отдельного маршрута обратного вызова для каждого провайдера НЕТ: ```text /callback ``` Например, независимо от того, используется ли Gemini, Antigravity, Cursor или GitLab Duo: - `https://omniroute.fly.dev/callback` Если `NEXT_PUBLIC_BASE_URL` не совпадает с URL-адресом обратного вызова, зарегистрированным у провайдера, процесс OAuth завершится ошибкой на этапе перенаправления в браузере. --- ## 7. Настройка секретов одной командой Следующие команды генерируют безопасные случайные значения и за один шаг записывают все необходимые параметры текущего проекта в Fly Secrets. Примечания: - Не включает `INITIAL_PASSWORD` - Предназначено для текущего проекта `omniroute` ```powershell $apiKeySecret = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() $jwtSecret = [Convert]::ToHexString((1..64 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() $machineIdSalt = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() $storageKey = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() $wsBridgeSecret = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() flyctl secrets set ` API_KEY_SECRET=$apiKeySecret ` JWT_SECRET=$jwtSecret ` MACHINE_ID_SALT=$machineIdSalt ` STORAGE_ENCRYPTION_KEY=$storageKey ` OMNIROUTE_WS_BRIDGE_SECRET=$wsBridgeSecret ` DATA_DIR=/data ` NEXT_PUBLIC_BASE_URL=https://omniroute.fly.dev ` -a omniroute ``` В Linux / macOS также можно использовать `openssl rand -hex 32`: ```bash flyctl secrets set OMNIROUTE_WS_BRIDGE_SECRET=$(openssl rand -hex 32) -a omniroute ``` Примечания: - `OMNIROUTE_WS_BRIDGE_SECRET` обязателен в рабочей среде; его отсутствие нарушит установление соединения с мостом WebSocket Если вы также хотите задать начальный пароль: ```powershell flyctl secrets set INITIAL_PASSWORD=your-strong-password -a omniroute ``` --- ## 8. Просмотр текущих параметров ```powershell flyctl secrets list -a omniroute ``` Если на странице `Secrets` в консоли не отображаются ожидаемые переменные, проверьте: - Что вы просматриваете приложение `omniroute` - Что значение `app` в `fly.toml` соответствует приложению в консоли --- ## 9. Последующие обновления и выпуски После обновления кода процесс выпуска прост: ```powershell git pull flyctl deploy ``` Если требуется только обновить параметры без изменения кода: ```powershell flyctl secrets set KEY=value -a omniroute ``` Fly автоматически выполнит поэтапное обновление машин. ### 9.1 Отслеживание обновлений вышестоящего репозитория с сохранением `fly.toml` вашего форка Если текущий репозиторий является форком и вы хотите синхронизировать обновления из вышестоящего репозитория `https://github.com/diegosouzapw/OmniRoute`, следуйте приведённому ниже процессу. Сначала проверьте удалённые репозитории: ```powershell git remote -v ``` Вы должны увидеть как минимум: - `origin`, указывающий на ваш собственный форк - `upstream`, указывающий на исходный репозиторий Если `upstream` не настроен, добавьте его: ```powershell git remote add upstream https://github.com/diegosouzapw/OmniRoute.git ``` Перед синхронизацией с вышестоящим репозиторием получите последние коммиты и теги: ```powershell git fetch upstream --tags ``` Проверьте текущую версию и теги вышестоящего репозитория: ```powershell git describe --tags --always git show --no-patch --oneline v3.4.7 ``` > Примечание: текущая версия проекта — `v3.8.0`. Приведённые ниже ссылки на `v3.4.7` сохранены исключительно в качестве исторических примеров. Для фактических выпусков используйте `:latest` или тег текущей версии (например, `:v3.8.0`). Если вы хотите выполнить слияние с последней версией вышестоящей ветки `main`, принудительно сохранив `fly.toml` вашего форка, следуйте этому процессу: ```powershell git merge upstream/main git checkout HEAD~1 -- fly.toml git add -- fly.toml git commit -m "chore(deploy): keep fork fly.toml" git push origin main ``` Примечания: - `git merge upstream/main` синхронизирует последний код из исходного репозитория - `git checkout HEAD~1 -- fly.toml` восстанавливает собственный файл `fly.toml` вашего форка из состояния до слияния - Если в вышестоящем репозитории файл `fly.toml` не изменялся, этот шаг не приведёт к появлению различий - Если в вышестоящем репозитории файл `fly.toml` был изменён, этот шаг гарантирует, что имя вашего приложения Fly, подключение тома, регион и другие параметры развёртывания, специфичные для форка, не будут перезаписаны Если вы хотите перейти на конкретный тег выпуска (например, `v3.4.7`), сначала убедитесь, что этот тег уже включён в `upstream/main`: ```powershell git merge-base --is-ancestor v3.4.7 upstream/main ``` Успешное выполнение означает, что `upstream/main` уже содержит эту версию; можно просто выполнить слияние с `upstream/main`. ### 9.2 Стандартная последовательность выпуска после синхронизации с вышестоящим репозиторием После синхронизации с исходным репозиторием соблюдайте следующий рекомендуемый порядок выпуска: 1. `git fetch upstream --tags` 2. `git merge upstream/main` 3. Восстановите файл `fly.toml` форка 4. `git push origin main` 5. `flyctl deploy` 6. `flyctl status -a omniroute` 7. `flyctl logs --no-tail -a omniroute` Это фактический процесс, использовавшийся при обновлении текущего проекта до `v3.4.7` (пример относится к исторической версии; текущая фактическая версия — `v3.8.0`). --- ## 10. Проверки после развертывания ### 10.1 Проверка состояния приложения ```powershell flyctl status -a omniroute ``` ### 10.2 Просмотр журналов запуска ```powershell flyctl logs --no-tail -a omniroute ``` ### 10.3 Проверка доступности сайта ```powershell try { (Invoke-WebRequest -Uri "https://omniroute.fly.dev" -MaximumRedirection 5 -UseBasicParsing).StatusCode } catch { if ($_.Exception.Response) { $_.Exception.Response.StatusCode.value__ } else { throw } } ``` Возвращаемое значение `200` означает, что сайт отвечает нормально. --- ## 11. Признаки успешного развертывания После успешного развертывания в журналах должно отображаться содержимое, подобное следующему: ```text [bootstrap] Secrets persisted to: /data/server.env [DB] SQLite database ready: /data/storage.sqlite ``` Критически важны следующие два момента: - `/data/server.env` подтверждает, что секреты среды выполнения записаны в постоянный том - `/data/storage.sqlite` подтверждает, что база данных записана в постоянный том Если вместо этого отображается `/app/data/...`, значит, `DATA_DIR` настроена неправильно и конфигурацию необходимо немедленно исправить. --- ## 12. Распространенные проблемы ### 12.1 Страница `Secrets` пуста Обычно это происходит по одной из двух причин: - Вы еще не запускали `flyctl secrets set` - Вы просматриваете другое приложение (например, `oroute` вместо `omniroute`) ### 12.2 `flyctl deploy` сообщает об ошибке `app not found` Сначала создайте приложение: ```powershell flyctl apps create omniroute ``` ### 12.3 Ошибка разбора `fly.toml` Проверьте следующее: - Нет ли искаженных символов в комментариях - Правильно ли используются кавычки и отступы в TOML ### 12.4 Данные не сохраняются Проверьте оба следующих условия: - `fly.toml` содержит `destination = '/data'` - Для `DATA_DIR` задано значение `/data` ### 12.5 Может ли приложение работать без `INITIAL_PASSWORD`? Да, может. В этом случае будет использоваться пароль по умолчанию `CHANGEME`. В рабочей среде рекомендуется как можно скорее изменить пароль серверной части. --- ## 13. Повторное использование для новых проектов Если вы развертываете новый проект согласно этому документу, необходимо изменить только следующие параметры: 1. Измените значение `app` в `fly.toml` 2. Измените `NEXT_PUBLIC_BASE_URL` 3. Сохраните `DATA_DIR=/data` 4. Заново сгенерируйте `API_KEY_SECRET`, `JWT_SECRET`, `MACHINE_ID_SALT` и `STORAGE_ENCRYPTION_KEY` 5. После первого развертывания убедитесь, что журналы записываются в `/data` Не используйте повторно ключи из предыдущего проекта. --- ## 14. Минимальный контрольный список выпуска для текущего проекта Наиболее часто используемые команды для последующих выпусков: ```powershell flyctl auth whoami flyctl status -a omniroute flyctl secrets list -a omniroute flyctl deploy flyctl logs --no-tail -a omniroute ``` Для обычного выпуска основной командой является: ```powershell flyctl deploy ``` При первом развертывании в новой среде необходимо выполнить следующие основные шаги: 1. `flyctl auth login` 2. `flyctl apps create omniroute` 3. `flyctl secrets set ... -a omniroute` 4. `flyctl deploy` 5. `flyctl logs --no-tail -a omniroute`