Представим приложение, которое мы назовём «Квитанция». Оно принимает от клиентов заявки на ремонт, сохраняет вложения, отправляет подтверждения на почту и после оплаты просит внешний сервис выпустить фискальный документ. Пример условный, но устроен он типично. Его перенесли с английского VPS на российский. Страницы открываются мгновенно, форма отвечает за долю секунды, пользователи довольны. А потом выясняется, что заявка принимается, письмо уходит, а чек не выпускается: один из запросов к внешнему API зависает и заканчивается таймаутом. В журнале аккуратная строка про превышение времени ожидания, и больше ничего.
Быстрый ответ главной страницы тут ничего не говорит. Приложение состоит не из одной точки входа, а из цепочки обращений наружу, и новая локация проверяет каждое звено по-своему. Ниже разберём, как найти эти звенья на примере «Квитанции» и как решить, что с каждым делать до переноса данных, а не после него.
Карта одного приложения вместо списка «зарубежных сайтов»
Первое искушение — выписать все иностранные домены, которые когда-либо встречались в проекте, и начать их проверять. Так получится длинный и бесполезный список: в нём окажутся и ссылка на шрифт из шаблона, и домен из комментария пятилетней давности. Полезнее составить карту обращений, которые приложение выполняет само, на живом сервере, в рабочем режиме. Для «Квитанции» карта выглядела бы так.
| Когда происходит | Что вызывается | Что будет при отказе |
|---|---|---|
| Пользователь отправил заявку | SMTP-сервер для подтверждения | Заявка сохранена, письмо не дошло |
| Загрузка вложения | Объектное хранилище | Заявку нельзя завершить |
| Успешная оплата | API выпуска чеков | Деньги получены, документа нет |
| Ночная задача | API курсов или справочников | Данные устаревают |
| Деплой | Registry, менеджер пакетов | Нельзя выпустить исправление |
| Запуск и раз в сутки | Сервер лицензий | Платный модуль отключается |
Заметьте, что последние две строки не видны пользователю вообще. Они проявятся не в день переезда, а в тот день, когда понадобится срочное обновление. Поэтому карту мы строим из двух источников: из кода и конфигурации и из фактического сетевого поведения.
Что искать в коде и в окружении
Начните с переменных окружения и файлов настроек: там живут адреса API, ключи, хосты SMTP, имена бакетов, адреса вебхуков. Затем пройдитесь по зависимостям: SDK поставщиков часто имеют зашитые базовые адреса и сами ходят по сети там, где вы этого не ожидали, например за телеметрией или проверкой лицензии. Отдельно просмотрите планировщик задач и фоновые воркеры: ночной крон, который раз в сутки скачивает справочник, на тестовой проверке в рабочее время просто не успеет себя показать.
Что видно только в живой сети
Код расскажет о намерениях, сеть покажет факты. Несколько дней понаблюдайте за исходящими соединениями на текущем английском сервере: к каким именам и портам обращается процесс приложения, как часто, какого размера ответы. Это можно сделать средствами, которые у вас уже есть: журналом прокси, логами межсетевого экрана, трассировкой запросов в самом приложении. Важно, чтобы наблюдение охватило хотя бы один полный цикл: сутки для ночных задач, а если есть месячные отчёты, то и их запуск вручную на тестовом стенде. Результат — таблица, подобная приведённой выше, но с реальными адресами и частотой.
Почему «открывается главная» ничего не доказывает
У «Квитанции» поставщик чеков имеет красивую посадочную страницу, которая спокойно открывается с любого узла. Это создаёт ложное чувство безопасности. Рабочий API часто живёт на другом имени, другом порту, за другим балансировщиком и под другими правилами, чем сайт для людей. Хуже того, он может отвечать по-разному на разные типы запросов: простой GET на корневой адрес проходит, а подписанный POST с телом заявки обрывается.
Поэтому проверка зависимости должна повторять реальный вызов, а не стучаться в вывеску. Для каждой строки карты нужен тест трёх уровней:
- Имя и маршрут. Адрес разрешается в DNS, соединение на нужный порт устанавливается, TLS-рукопожатие завершается без ошибок сертификата.
- Аутентифицированный вызов. Запрос с настоящим (тестовым, если поставщик его даёт) ключом возвращает осмысленный ответ, а не отказ по сети или по политике.
- Полный рабочий сценарий. Именно то действие, ради которого интеграция существует: выпустить чек в тестовом режиме, загрузить файл и скачать его обратно, отправить письмо и увидеть его на принимающей стороне.
Первый уровень отвечает на вопрос «дойдёт ли пакет», второй — «пустят ли нас», третий — «работает ли бизнес-операция». Для «Квитанции» провал случился именно на втором-третьем уровне: соединение устанавливается, но ответ не приходит. Узнать причину из одного лишь таймаута нельзя: это может быть фильтрация на пути, ограничение на стороне поставщика, блокировка по диапазону адресов или просто перегруженный эндпоинт. Отсюда правило: фиксируйте не «не работает», а на каком из трёх уровней и с каким точным симптомом остановились: отказ в соединении, обрыв на рукопожатии, код ответа или тишина.
Почта: у отправителя есть собственные условия
Почтовая цепочка заслуживает отдельного разбора, потому что при переезде меняется то, что ящики-получатели видят о вашем сервере: его адрес. Требования крупных почтовых систем к отправителям опираются на репутацию и техническую корректность. Например, в правилах Gmail для отправителей указано, что нужны SPF или DKIM, корректные прямые и обратные DNS-записи и TLS, а для массовой рассылки требования строже (Gmail email sender guidelines).
Что это значит для переезда. Если «Квитанция» отправляла письма напрямую со своего английского сервера, то SPF-запись перечисляет его адрес, а обратная запись этого адреса указывает на ваше имя. На новом сервере всё это придётся пересоздать: новый адрес не будет в SPF, а обратная запись настраивается на стороне владельца адресного блока, то есть через панель или обращение к поставщику VPS. Если же письма идут через внешнего почтового провайдера по SMTP, то вопрос смещается: нужно проверить, что ваш новый сервер вообще способен достучаться до его SMTP-порта и что провайдер не ограничивает вход по условиям вашей учётной записи.
Соответствие перечисленным пунктам не гарантирует, что письмо окажется во входящих: оно лишь убирает самые очевидные причины отказа. Поэтому тест почты на новом узле — это не «письмо ушло без ошибки», а три наблюдения: сервер принял и отправил сообщение, на приёмной стороне видны результаты проверки SPF/DKIM для вашего домена, и письмо попало не только в тестовый ящик на вашем же домене, но и во внешний.
Путь обновления: то, что ломается позже всего
Теперь строки «деплой» и «лицензия». Они опасны тем, что сегодня приложение уже установлено и работает, а проблема проявится только при следующей сборке. Поэтому проверять их нужно искусственно: собрать проект с нуля на новом узле, как будто у вас ничего нет в кэше.
Менеджер пакетов и lock-файл
Для Node.js-проекта вроде «Квитанции» опорой служит lock-файл: package-lock.json фиксирует точное дерево установленных зависимостей, чтобы последующие установки были воспроизводимыми (npm package-lock.json). Это значит, что на чистом сервере вы получите те же версии пакетов, но не значит, что они откуда-то возьмутся: пакеты всё равно нужно скачать из реестра, а в lock-файле записаны адреса, откуда это делалось. Если часть пакетов тянется из частного реестра, с git-репозитория или с адреса, доступного только из прежнего окружения, чистая установка упадёт именно там. Заодно стоит помнить: ссылка на документацию версии 11 не означает, что на вашем сервере стоит такая же версия npm, это нужно проверить самим.
Практика такая: на новом узле в пустом каталоге выполните установку строго по lock-файлу, замеряйте, какие обращения наружу она делает, и запишите, сколько времени и какие адреса понадобились. Затем отдельно повторите это для сборки образа.
Образы контейнеров и digest
С контейнерами тот же сюжет, но с важным нюансом. Теги образов изменяемы: тот же :latest или :20 сегодня и через месяц может указывать на разные образы. Закрепление по digest фиксирует конкретный образ (Docker build best practices). Но здесь есть оборотная сторона: закреплённый digest не подтягивает будущие исправления сам, обновление требует отдельного действия.
Для переезда это даёт два вывода. Во-первых, закрепление помогает убедиться, что на новом узле запускается ровно то, что работало в UK. Во-вторых, оно делает путь обновления явным решением: когда выйдет исправление безопасности базового образа, кто-то должен его заметить, получить новый digest, пересобрать и проверить. А значит, вопрос «откуда мы скачиваем образы» — не разовый, а постоянный. Если источник базовых образов недоступен или нестабилен с нового узла, то стоит заранее решить, где будет лежать ваша копия: во внутреннем registry на собственном сервере или в другом хранилище, к которому доступ вы проверили полным циклом — вход, загрузка, скачивание.
Лицензии и проверки «по расписанию»
Отдельная тема — платные компоненты, которые сверяются с сервером поставщика при старте или раз в сутки. Их легко забыть, потому что в обычный день они не вызывают ничего заметного. Выясните по документации поставщика, как именно привязана лицензия: к домену, к адресу сервера, к учётной записи. Если лицензия привязана к IP, смена локации потребует её перевыпуска. Если к учётной записи, возникает следующий вопрос, о котором речь пойдёт ниже.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации Россия, США, Франция и Великобритания. Оплата картой РФ и по СБП.
Сеть открыта, а аккаунт — нет
Бывает, что сетевой путь у поставщика есть, но условия использования его услуг зависят от страны регистрации учётной записи, платёжных средств и политики самого поставщика. Это самостоятельный слой проверки, который сетевой тест не раскрывает: соединение может устанавливаться, а аккаунт получить отказ по правилам сервиса. Мы здесь не даём юридических оценок и не утверждаем, что какая-то страна размещения автоматически что-то разрешает или запрещает: решать эти вопросы нужно по условиям конкретного поставщика, а при необходимости с юристом.
Практичный подход — для каждой внешней зависимости записать три вещи отдельно:
- на чьём аккаунте и на какой платёжный способ оформлена услуга;
- какие условия поставщика описывают допустимые страны и способы оплаты;
- что случится с интеграцией, если поставщик приостановит доступ: останется ли возможность выгрузить свои данные.
Третий пункт напоминает о соседней теме: когда ключевая услуга оформлена на чужом аккаунте, потеря доступа становится проблемой бизнеса. Об этой ловушке подробнее в материале про сервер, который подрядчик держит на своём аккаунте.
Обязательное и заменяемое
Когда карта заполнена и проверена, зависимости полезно разделить на два класса. Критерий простой: что произойдёт, если звено исчезнет на неделю.
| Зависимость | Класс | Варианты решения |
|---|---|---|
| API выпуска чеков | Обязательная, без аналога в тот же день | Проверить полный сценарий с нового узла; заранее найти альтернативного поставщика и изучить его интеграцию |
| Объектное хранилище вложений | Заменяемая | Перенести в хранилище на своём сервере или в другом месте, проверить скачивание |
| SMTP | Заменяемая | Другой провайдер или собственный MTA с SPF, DKIM, обратной записью |
| Registry и пакеты | Заменяемая с подготовкой | Локальное зеркало или собственный registry, закрепление digest |
| Справочники и курсы | Заменяемая, терпит задержку | Кэш последних значений, ручное обновление |
| Лицензия платного модуля | Зависит от договора | Уточнить условия, перевыпустить или заменить модуль |
Обязательной зависимость становится не потому, что она «важная», а потому что у неё нет замены, которую можно включить быстро. «Квитанция» без выпуска чеков хуже, чем без красивых писем: деньги приняты, а документа нет. Для такой зависимости до переноса записей нужно либо подтверждённо работающий путь с нового узла, либо запасной маршрут, например отдельный промежуточный сервис в другой локации, через который идут только эти вызовы. Но и такой маршрут нужно проверять тем же трёхуровневым тестом, и его появление означает, что вы добавили в схему ещё одно звено, которое тоже нужно обслуживать и защищать. Не стоит считать его бесплатным решением: это новая зависимость внутри вашей архитектуры.
Заменяемые зависимости полезно именно заменить, а не терпеть. Хранилище вложений — типичный кандидат на переезд вместе с приложением: файлы лежат ближе к коду, а число внешних обращений падает. Почту можно оставить на внешнем провайдере, если он доступен и подходит по условиям, а можно развернуть собственную отправку, но тогда на вас ложатся настройки SPF, DKIM, обратной записи и поддержка репутации.
Проверка на российском узле до переноса записей
Теперь собираем всё в репетицию. Мы поднимаем новый сервер, на нём проверяем схему целиком, а рабочие записи переносим только после этого. Для такой проверки подойдёт небольшой VPS: в линейке MAATRIX начальный тариф Ba даёт 1 vCPU, 2 ГБ RAM и 40 ГБ NVMe, дальше идут Uab (2 vCPU, 4 ГБ, 80 ГБ) и Heka (4 vCPU, 8 ГБ, 160 ГБ). Это отправная точка для теста, а не обещание ёмкости: настоящую нагрузку покажет репетиция. В публичном предложении указаны локации UK, US, RU и FR, а точное наличие образов и ОС в выбранной локации уточняется в форме заказа. Доступ к серверу — root, так что поставить нужные инструменты диагностики можно самому.
Порядок репетиции для «Квитанции» такой.
- Чистая сборка. На пустом узле установить зависимости по lock-файлу и собрать образы без кэша, фиксируя все внешние адреса, которые понадобились.
- Восстановление данных. Развернуть копию базы из свежего экспорта. Если это PostgreSQL, учтите, что
pg_dumpсоздаёт согласованный экспорт одной базы даже при параллельной работе пользователей, но глобальные роли и tablespaces им не охватываются, для них предусмотренpg_dumpall(PostgreSQL pg_dump). Если роли не перенести, приложение на новом узле может не получить прав, а ошибка будет выглядеть как проблема сети. - Тесты по карте. Для каждой строки карты прогнать трёхуровневую проверку и записать результат.
- Сценарий целиком. Пройти путь клиента от заявки до чека в тестовом режиме поставщиков, а не вручную выдёргивая отдельные запросы.
- Имитация обновления. Выпустить небольшое изменение и убедиться, что оно проходит сборку, доставку образа и запуск на новом узле без помощи кэша.
Ночные задачи на репетиции дожидаться неудобно, поэтому запустите их вручную с тестовыми данными и посмотрите, куда они ходят.
Когда переключать и когда оставаться
Критерии стоит записать заранее, пока нет давления дедлайна. Например: все обязательные зависимости прошли три уровня проверки; для каждой заменяемой выбрано место размещения и оно проверено; чистая сборка и обновление выполнены без обращений к неучтённым адресам; восстановление базы воспроизводимо. Если один из пунктов провален, переезд откладывается или схема меняется. Обратный путь тоже нужно продумать: пока английский сервер работает, он остаётся эталоном, а новые записи, сделанные на российском узле после переключения, придётся при откате переносить обратно. Поэтому окно между переключением и признанием переезда удачным лучше сделать коротким, а наблюдение за обращениями — подробным.
Решение для каждой зависимости
Итог работы — не абстрактная уверенность, а перечень решений с названием каждой нужной зависимости и места, где она будет жить. Для условной «Квитанции» он мог бы выглядеть так:
- Выпуск чеков: остаётся внешним. Решение принимается после полного тестового сценария с российского узла и сверки условий учётной записи; пока не пройдено — запасной маршрут или альтернативный поставщик, но не перенос записей.
- Вложения: переезжают на хранилище рядом с приложением, скачивание проверено на реальных файлах.
- Почта: внешний SMTP-провайдер, если доступ и условия подтверждены, либо собственная отправка с настроенными SPF, DKIM, прямой и обратной записью и TLS.
- Образы и пакеты: базовые образы закреплены по digest и хранятся в доступном для нового узла registry; процедура осознанного обновления закреплённых образов описана и назначен ответственный.
- Справочники: кэш последних значений и понятная реакция на отказ источника.
- Лицензия: условия уточнены, привязка проверена, при необходимости модуль заменён.
Если нужен чистый стенд для такой репетиции, подойдёт отдельный VPS в российской локации: поднять его можно за пару минут после оплаты картой РФ или через СБП, а дальше вы сами решаете, что на нём будет жить. Хороший результат подготовки — когда после переезда вы не удивляетесь молчащему вызову, потому что ещё до переключения знали, где проходит каждая нить и кто её держит.