Представим приложение, которое мы назовём «Квитанция». Оно принимает от клиентов заявки на ремонт, сохраняет вложения, отправляет подтверждения на почту и после оплаты просит внешний сервис выпустить фискальный документ. Пример условный, но устроен он типично. Его перенесли с английского VPS на российский. Страницы открываются мгновенно, форма отвечает за долю секунды, пользователи довольны. А потом выясняется, что заявка принимается, письмо уходит, а чек не выпускается: один из запросов к внешнему API зависает и заканчивается таймаутом. В журнале аккуратная строка про превышение времени ожидания, и больше ничего.

Быстрый ответ главной страницы тут ничего не говорит. Приложение состоит не из одной точки входа, а из цепочки обращений наружу, и новая локация проверяет каждое звено по-своему. Ниже разберём, как найти эти звенья на примере «Квитанции» и как решить, что с каждым делать до переноса данных, а не после него.

Карта одного приложения вместо списка «зарубежных сайтов»

Первое искушение — выписать все иностранные домены, которые когда-либо встречались в проекте, и начать их проверять. Так получится длинный и бесполезный список: в нём окажутся и ссылка на шрифт из шаблона, и домен из комментария пятилетней давности. Полезнее составить карту обращений, которые приложение выполняет само, на живом сервере, в рабочем режиме. Для «Квитанции» карта выглядела бы так.

Исходящие обращения приложения «Квитанция» (условный пример)
Когда происходитЧто вызываетсяЧто будет при отказе
Пользователь отправил заявкуSMTP-сервер для подтвержденияЗаявка сохранена, письмо не дошло
Загрузка вложенияОбъектное хранилищеЗаявку нельзя завершить
Успешная оплатаAPI выпуска чековДеньги получены, документа нет
Ночная задачаAPI курсов или справочниковДанные устаревают
ДеплойRegistry, менеджер пакетовНельзя выпустить исправление
Запуск и раз в суткиСервер лицензийПлатный модуль отключается

Заметьте, что последние две строки не видны пользователю вообще. Они проявятся не в день переезда, а в тот день, когда понадобится срочное обновление. Поэтому карту мы строим из двух источников: из кода и конфигурации и из фактического сетевого поведения.

Что искать в коде и в окружении

Начните с переменных окружения и файлов настроек: там живут адреса API, ключи, хосты SMTP, имена бакетов, адреса вебхуков. Затем пройдитесь по зависимостям: SDK поставщиков часто имеют зашитые базовые адреса и сами ходят по сети там, где вы этого не ожидали, например за телеметрией или проверкой лицензии. Отдельно просмотрите планировщик задач и фоновые воркеры: ночной крон, который раз в сутки скачивает справочник, на тестовой проверке в рабочее время просто не успеет себя показать.

Что видно только в живой сети

Код расскажет о намерениях, сеть покажет факты. Несколько дней понаблюдайте за исходящими соединениями на текущем английском сервере: к каким именам и портам обращается процесс приложения, как часто, какого размера ответы. Это можно сделать средствами, которые у вас уже есть: журналом прокси, логами межсетевого экрана, трассировкой запросов в самом приложении. Важно, чтобы наблюдение охватило хотя бы один полный цикл: сутки для ночных задач, а если есть месячные отчёты, то и их запуск вручную на тестовом стенде. Результат — таблица, подобная приведённой выше, но с реальными адресами и частотой.

Почему «открывается главная» ничего не доказывает

У «Квитанции» поставщик чеков имеет красивую посадочную страницу, которая спокойно открывается с любого узла. Это создаёт ложное чувство безопасности. Рабочий API часто живёт на другом имени, другом порту, за другим балансировщиком и под другими правилами, чем сайт для людей. Хуже того, он может отвечать по-разному на разные типы запросов: простой GET на корневой адрес проходит, а подписанный POST с телом заявки обрывается.

Поэтому проверка зависимости должна повторять реальный вызов, а не стучаться в вывеску. Для каждой строки карты нужен тест трёх уровней:

  1. Имя и маршрут. Адрес разрешается в DNS, соединение на нужный порт устанавливается, TLS-рукопожатие завершается без ошибок сертификата.
  2. Аутентифицированный вызов. Запрос с настоящим (тестовым, если поставщик его даёт) ключом возвращает осмысленный ответ, а не отказ по сети или по политике.
  3. Полный рабочий сценарий. Именно то действие, ради которого интеграция существует: выпустить чек в тестовом режиме, загрузить файл и скачать его обратно, отправить письмо и увидеть его на принимающей стороне.

Первый уровень отвечает на вопрос «дойдёт ли пакет», второй — «пустят ли нас», третий — «работает ли бизнес-операция». Для «Квитанции» провал случился именно на втором-третьем уровне: соединение устанавливается, но ответ не приходит. Узнать причину из одного лишь таймаута нельзя: это может быть фильтрация на пути, ограничение на стороне поставщика, блокировка по диапазону адресов или просто перегруженный эндпоинт. Отсюда правило: фиксируйте не «не работает», а на каком из трёх уровней и с каким точным симптомом остановились: отказ в соединении, обрыв на рукопожатии, код ответа или тишина.

Почта: у отправителя есть собственные условия

Почтовая цепочка заслуживает отдельного разбора, потому что при переезде меняется то, что ящики-получатели видят о вашем сервере: его адрес. Требования крупных почтовых систем к отправителям опираются на репутацию и техническую корректность. Например, в правилах 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, так что поставить нужные инструменты диагностики можно самому.

Порядок репетиции для «Квитанции» такой.

  1. Чистая сборка. На пустом узле установить зависимости по lock-файлу и собрать образы без кэша, фиксируя все внешние адреса, которые понадобились.
  2. Восстановление данных. Развернуть копию базы из свежего экспорта. Если это PostgreSQL, учтите, что pg_dump создаёт согласованный экспорт одной базы даже при параллельной работе пользователей, но глобальные роли и tablespaces им не охватываются, для них предусмотрен pg_dumpall (PostgreSQL pg_dump). Если роли не перенести, приложение на новом узле может не получить прав, а ошибка будет выглядеть как проблема сети.
  3. Тесты по карте. Для каждой строки карты прогнать трёхуровневую проверку и записать результат.
  4. Сценарий целиком. Пройти путь клиента от заявки до чека в тестовом режиме поставщиков, а не вручную выдёргивая отдельные запросы.
  5. Имитация обновления. Выпустить небольшое изменение и убедиться, что оно проходит сборку, доставку образа и запуск на новом узле без помощи кэша.

Ночные задачи на репетиции дожидаться неудобно, поэтому запустите их вручную с тестовыми данными и посмотрите, куда они ходят.

Когда переключать и когда оставаться

Критерии стоит записать заранее, пока нет давления дедлайна. Например: все обязательные зависимости прошли три уровня проверки; для каждой заменяемой выбрано место размещения и оно проверено; чистая сборка и обновление выполнены без обращений к неучтённым адресам; восстановление базы воспроизводимо. Если один из пунктов провален, переезд откладывается или схема меняется. Обратный путь тоже нужно продумать: пока английский сервер работает, он остаётся эталоном, а новые записи, сделанные на российском узле после переключения, придётся при откате переносить обратно. Поэтому окно между переключением и признанием переезда удачным лучше сделать коротким, а наблюдение за обращениями — подробным.

Решение для каждой зависимости

Итог работы — не абстрактная уверенность, а перечень решений с названием каждой нужной зависимости и места, где она будет жить. Для условной «Квитанции» он мог бы выглядеть так:

  • Выпуск чеков: остаётся внешним. Решение принимается после полного тестового сценария с российского узла и сверки условий учётной записи; пока не пройдено — запасной маршрут или альтернативный поставщик, но не перенос записей.
  • Вложения: переезжают на хранилище рядом с приложением, скачивание проверено на реальных файлах.
  • Почта: внешний SMTP-провайдер, если доступ и условия подтверждены, либо собственная отправка с настроенными SPF, DKIM, прямой и обратной записью и TLS.
  • Образы и пакеты: базовые образы закреплены по digest и хранятся в доступном для нового узла registry; процедура осознанного обновления закреплённых образов описана и назначен ответственный.
  • Справочники: кэш последних значений и понятная реакция на отказ источника.
  • Лицензия: условия уточнены, привязка проверена, при необходимости модуль заменён.

Если нужен чистый стенд для такой репетиции, подойдёт отдельный VPS в российской локации: поднять его можно за пару минут после оплаты картой РФ или через СБП, а дальше вы сами решаете, что на нём будет жить. Хороший результат подготовки — когда после переезда вы не удивляетесь молчащему вызову, потому что ещё до переключения знали, где проходит каждая нить и кто её держит.