Как мы подготовили сайт на shared hosting к обслуживанию с Cloudflare Workers
Короткий ответ
PHP-сайт с преимущественно статическим содержимым может оставаться полезным во время планового простоя без переноса живого аккаунта. Worker перед KeyboardTester.click пропускает здоровый ответ без изменений, а при сетевой ошибке или выбранных ошибках сервера отдает подготовленный снимок. После восстановления следующий здоровый запрос автоматически возвращается к origin. Это практичная непрерывность, а не универсальный zero downtime: формы, почта, серверный ИИ и сохранение по-прежнему зависят от хостинга.
В уведомлении было шестичасовое окно, но не точное время простоя. Ожидание письма оставляло ручной промежуток; перевод DNS на одну страницу сохранял объявление, но не контент и браузерные инструменты.
Ниже реальная схема: переписка с HostArmada, логика Worker, снимок, рекурсия в одной зоне, защита бесплатного тарифа, SEO, реклама, аналитика и честные границы.
Важная дата: на 18 июля 2026 года плановое обслуживание еще не состоялось. Результаты получены при принудительном сбое origin, в закрытом staging, полном аудите снимка и здоровом live pass-through, а не в реальном окне работ.
Что прояснил тикет HostArmada
Работы были назначены на 22 июля 2026 года с 10:00 до 16:00 CDT. Мы спросили, означает ли это шесть часов непрерывного простоя, возможен ли временный перенос, какие сервисы пострадают, можно ли дать внешний 503 для каждого URL, каковы rollback и компенсация.
После эскалации администрация уточнила: шесть часов — резервное окно, а не гарантированная длительность. Реальный перерыв ожидался короче, но точность невозможна из-за замены оборудования, обновлений и проверки. Перенос аккаунта туда и обратно добавляет риски DNS, синхронизации, почты и БД.
HostArmada разумно предложила временный vhost на другом сервере с ручной сменой A-записи в начале и конце. Внешний DNS продолжит разрешаться, но web, БД, почта и панель исходного сервера будут недоступны. Резервное копирование и восстановление предусмотрены; кредит рассматривается по фактическому влиянию. Для объявления это честное решение, но оно ручное и не сохраняет функциональный сайт.
That offer was fair for a maintenance notice. It was still manual and did not provide functional-site continuity, so we used it as the baseline to improve rather than portraying it as a provider failure.
Проверяемая хронология: от письма до протестированного fallback
Она отделяет объявление, наши вопросы, реально собранное и проверенное решение от еще не наступившего события.
- Июль 2026 — письмо
Уведомление Start Dock зарезервировало 22 июля 10:00–16:00 CDT: CPU/RAM/SSD, безопасность/ПО web-сервера, kernel, очистка tmp/cache/logs, оптимизация. После старта процедура описана как необратимая.
- Сервер shared hosting Start Dock
- 22 июля 2026, 10:00–16:00 CDT
- Апгрейд CPU, RAM и SSD
- Безопасность/ПО web-сервера
- Обновление kernel
- Очистка tmp, cache и logs
- Общая оптимизация
- После старта процедура необратима
- 16 июля — вопросы эскалированы
Реальный downtime, миграция, внешний 503, web/DB/email, backup, rollback и кредит.
- 17 июля — ответ HostArmada
Шесть часов — окно; перерыв вероятно короче. Миграция отклонена из-за синхронизации, предложены vhost и ручной A-record.
- Дизайн выбран 17 июля; follow-up отправлен 18 июля
Постоянный origin-first Worker, snapshot, private staging, collision checks, 503 и rollback.
- 17–18 июля — контролируемые тесты
1 514 страниц, 1 234 ресурса, 2 748 путей; тесты сбоя/прохода, исправление рекурсии, apex/www fail-open.
- 18 июля — готово, событие впереди
Слой live и проверен; обслуживание 22-го еще не было. Реальные длительность, traffic и доход ждут постфактум.


Архитектура: сначала origin, снимок только при сбое
Worker постоянно стоит на apex- и www-маршрутах и проверяет реальный origin с ограниченным таймаутом. Здоровый ответ идет без изменений, поэтому PHP, сессии, заголовки, реклама и аналитика работают обычно.
При сетевой ошибке, таймауте, 500, 502, 503, 504 или 520–527 Worker ищет тот же путь в статических ресурсах. GET/HEAD продолжаются; каждый следующий запрос снова пробует origin, поэтому возврат автоматический.
Снимок намеренно не является вторым PHP-стеком: нет двух записываемых БД, конфликтов сессий и последующей сверки данных.
Путь запроса

Страница провайдера или непрерывность через Worker?
Для корректного сообщения о работах достаточно временной страницы. Для сохранения читаемых страниц и клиентских инструментов нужен заранее проверенный статический снимок.
| Вопрос | Временный vhost | Постоянный Worker |
|---|---|---|
| Переключение | DNS вручную в начале и конце | Автоматически на запрос |
| Что видит посетитель | Одна страница работ | Соответствующая страница, инструмент или ресурс |
| Запись | Недоступна | Недоступна; явный 503 |
| Восстановление | DNS вернуть вручную | Автоматически при здоровом origin |
| Целостность | Низкий риск без второй БД | Низкий риск без второй БД |
| Операции | Просто, но требует действия вовремя | Больше подготовки, мало действий во время события |
Что получают посетители и роботы
Страницы, браузерные инструменты, CSS, скрипты, изображения и шрифты идут из снимка с небольшим уведомлением. Canonical и структурированные данные остаются на исходных URL.
Запись не имитирует успех: POST и недоступные действия получают 503 Service Unavailable, Retry-After: 300 и Cache-Control: no-store, как предусмотрено RFC 9110 для временного обслуживания.
This distinction matters: returning a pretty 200 OK “maintenance” page for a failed form can mislead users and crawlers. Returning a controlled 503 for the unavailable action is both more honest and easier for clients to retry.
Фактическая матрица fallback
| Ответ origin | GET / HEAD | POST или запись |
|---|---|---|
| Здоровый, redirect, 4xx или вне списка | Передать origin без изменений | Передать origin без изменений |
| Сеть или timeout 4,5 с | Соответствующий snapshot; иначе 503 | 503 + Retry-After: 300 + no-store |
| 500/502/503/504 или 520–527 | Snapshot и диагностический header | 503 + Retry-After: 300 + no-store |
| Неизвестный safe path без origin | Контролируемый 503; не выдумывать страницу | Не применимо |
Как мы собрали и проверили снимок
Мы сканировали отрисованный production, а не локальное PHP-дерево с неопубликованными изменениями. Получили 1 514 страниц, 1 234 собственных ресурса и пакет из 2 749 файлов около 547,6 МБ; каждый файл ниже лимита.
Canonical и schema сохранены, старые относительные ссылки исправлены только в копии. Трекеры удалены при захвате; production Worker добавляет GA4, AdSense и Clarity лишь на главной. Закрытый staging остается без tracking и с noindex.
QA включал TypeScript, unit, принудительный локальный сбой, авторизованный staging, браузер, origin preview и полный удаленный аудит: все 2 748 публичных путей страниц/ресурсов прошли.
- Разделите окно работ и ожидаемый простой.
- Собирайте с отрисованного production, если local не идентичен.
- Инвентаризируйте страницы/ресурсы и проверьте число/размер.
- Держите staging закрытым/noindex; тестируйте сбой и pass-through.
- Заранее задайте методы, статусы, timeout, 503 и rollback.
- Исключите рекурсию одной зоны и сохраните canonical Host.
- Выбирайте fail-open, только если обход Worker безопаснее.
- Опишите недоступные функции и обновляйте снимок.

Безопасное воспроизведение: шаги и очищенный код
1. Задайте контракт. Hosts, безопасные методы, статусы, timeout, неизвестные пути и снятие routes. Не любой non-200 означает сбой.
2. Сканируйте отрисованный production. От canonical sitemap собирайте только same-origin HTML/CSS, нормализуйте URL, блокируйте traversal и останавливайте build при лимитах.
3. Сохраните смысл. Canonical, hreflang, schema, ссылки и client assets оставить; service worker/tracking убрать. Рекламу/аналитику добавлять только production.
4. ASSETS + run_worker_first. Сначала проверяется origin; примеры используют только placeholders.
5. Исключите рекурсию. Контролируемое DNS-only имя той же зоны для resolveOverride, canonical URL/Host, тест TLS/vhost.
6. Закрытый staging. Secret, noindex, robots block, без рекламы/аналитики, origin preview.
7. Apex, затем www. Отказывать при collision, проверить redirect; fail-open только для доступности.
8. Отделите rollback. Снять только свои routes, оставить Worker/snapshot и отозвать временные права.
Очищенная конфигурация Worker/assets
{
"name": "example-host-outage-fallback",
"main": "src/index.ts",
"compatibility_date": "2026-07-17",
"assets": {
"directory": "./snapshot/dist",
"binding": "ASSETS",
"run_worker_first": true,
"html_handling": "none",
"not_found_handling": "none"
},
"vars": {
"MODE": "production",
"ORIGIN_BASE": "https://example.com",
"ORIGIN_RESOLVE_OVERRIDE": "origin-bypass.example.com",
"ORIGIN_TIMEOUT_MS": "4500"
}
}Origin-first и матрица статусов
const FALLBACK_STATUSES = new Set([
500, 502, 503, 504, 520, 521, 522, 523, 524, 525, 526, 527
]);
try {
const origin = await fetch(originRequest, {
signal: AbortSignal.timeout(4500),
redirect: "manual",
cf: { resolveOverride: "origin-bypass.example.com" }
});
if (!FALLBACK_STATUSES.has(origin.status)) return origin;
return serveSnapshot(request, origin.status);
} catch {
return serveSnapshot(request);
}Честный 503 для записи
if (!new Set(["GET", "HEAD"]).has(request.method)) {
return new Response("Temporarily unavailable", {
status: 503,
headers: {
"Retry-After": "300",
"Cache-Control": "no-store",
"Content-Type": "text/plain; charset=utf-8"
}
});
}Build, staging, activation, rollback
# Build from rendered production and validate the package
python scripts/build_snapshot.py
npm run types
npm run check
npx wrangler deploy --env staging --dry-run
# Deploy and test the private preview (use your own secret securely)
npx wrangler deploy --env staging
python scripts/smoke_staging.py --base "https://<private-preview>" --password "<secret>"
# Inspect, activate, or remove only the owned routes
python scripts/manage_routes.py status
python scripts/manage_routes.py activate --confirm ACTIVATE-KBT-FALLBACK
python scripts/manage_routes.py deactivate --confirm REMOVE-KBT-FALLBACKПлан тестов: доказать сбой, проход и восстановление
Главная, основной tool, CSS/JS, статья, Arabic RTL, длинная локализация, robots, missing path, HEAD, POST, www redirect и mobile themes.
Snapshot: header, canonical, H1, JSON-LD, assets, notice. Origin preview: без loop. Здоровый production: нет fallback header, ответ не изменен.
Не ломайте публичный origin. Используйте private preview/test origin и фиксируйте время снимка и manifest hash.
Откат, мониторинг и восстановление
Немедленный откат — удалить только свои Worker routes, не менять DNS и не удалять Worker. Проверить apex/www, purge лишь при старом HTML.
Во время работ следить за headers, origin status, logs, ключевыми страницами и 503. Первый здоровый ответ восстанавливает автоматически. Затем проверить стабильность, отозвать права, сохранить метрики и обновить снимок.
Две ловушки: рекурсия в зоне и бесплатный лимит
Worker на keyboardtester.click/* не должен наивно fetch того же публичного хоста. resolveOverride с существующим DNS-only именем в той же зоне направляет разрешение к origin, сохраняя канонические URL и Host. Адрес origin и обходной путь нельзя публиковать.
Free сейчас дает 100 000 Worker-запросов в день, 20 000 статических файлов на версию и 25 MiB на файл. Наши 2 749 помещаются. Маршруты fail-open: при исчерпании Cloudflare идет прямо к HostArmada вместо Error 1027. Это верно для доступности, но не для обязательного security-контроля.
SEO, реклама и аналитика в fallback
Существующие страницы отвечают 200 на исходных URL с canonical, schema и ссылками; недоступная запись получает 503. Нет публичного зеркального домена и новых URL для отправки.
Staging защищен паролем, закрыт robots, имеет noindex и без измерения. Только production snapshot HTML получает отложенные GA4/AdSense и Clarity на главной. Здоровый origin не меняется. Измерение и шанс показа сохраняются, но заполнение и доход не гарантируются.
We did not submit fallback URLs to search engines because there are no new public URLs. The continuity layer sits behind the same addresses Google already knows.
Production-инъекция повторяет live: GA4 после взаимодействия или через 2 секунды load, AdSense после взаимодействия или 15 секунд, Clarity главной — после взаимодействия или 12 секунд. Потоковый HTMLRewriter меняет только fallback GET HTML, не HEAD, CSS, JS и изображения.
Ограничения и когда нужна другая схема
Формы, серверный ИИ, почта, записи БД, сессии и сохраненные отправки не работают без origin. Браузерный инструмент работает, только если все нужные файлы попали в снимок.
Снимок устаревает: обновляйте его после значимых изменений и проверяйте восстановление. Транзакционному или write-heavy продукту нужны репликация приложения и БД.
Для контентного сайта на shared hosting с клиентскими инструментами подход подошел: без разделения данных, ручного переключения и второго публичного домена, с ясным режимом деградации. Он уменьшает видимый простой, но не отменяет зависимости.
Первичные источники и прямые доказательства
Цифры взяты из манифестов и проверок деплоя/маршрутов 17–18 июля 2026 года. Поведение и лимиты подтверждены первичной документацией по ссылкам.
- Cloudflare Workers: Static Assets
- Cloudflare Workers: Platform Limits
- Cloudflare Workers Request API
- Cloudflare Workers Routes API
- RFC 9110: HTTP Semantics
- HostArmada support correspondence, July 16–17, 2026
Частые вопросы
- Это делает shared hosting полностью безотказным?
Нет. Читаемая копия остается, но формы, запись, почта, ИИ и сессии требуют origin.
- Нужно ли менять DNS при сбое?
Нет в этой постоянной схеме. Worker проверяет каждый запрос и возвращается автоматически.
- Google увидит страницу обслуживания на каждом URL?
Нет. Скопированные страницы сохраняют 200, canonical/schema; недоступные действия временно получают 503.
- Почему не перенести весь аккаунт временно?
Перенос туда-обратно добавляет риски DNS, файлов, почты и синхронизации БД.
- Зачем resolveOverride?
Чтобы Worker не вызывал собственный публичный маршрут. Разрешение идет через другое имя той же зоны, URL/Host сохраняются.
- Что будет при бесплатном лимите?
Fail-open обходит Worker к origin. При падении origin fallback исчезнет, но дополнительной ошибки квоты не будет.
- Когда обновлять снимок?
После крупных изменений и перед обслуживанием, проверяя сбой и восстановление.
Вывод не в том, чтобы поставить все за Worker: выберите минимальный слой под свой сбой, тестируйте закрыто, честно назовите пределы и автоматизируйте восстановление.