Практическое руководство: построение простого CDN на базе VPS и Cloudflare

Когда VPS начинает упираться в лимиты по CPU или сетевому трафику, а метрики показывают, что 80% запросов — это повторные обращения к статике, самое время подумать о кэшировании на стороне клиента. Но если хочется большего — снять нагрузку с origin-сервера, отдавать файлы ближе к пользователям и заодно прикрыться от простых атак — связка VPS + Cloudflare даёт быстрый и недорогой путь к «мини-CDN». Это не полноценная глобальная сеть доставки контента в классическом понимании, а рабочая схема, где Cloudflare берёт на себя edge-кэширование, TLS, базовую защиту и часть логики доставки, а VPS остаётся источником данных.

Собрать такую конструкцию можно за один вечер, если понимать, какие рычаги за что отвечают. Дальше разберу, как это выглядит на практике, на что обращать внимание и где легко наступить на грабли.

Что именно мы строим

Логика работы проста и укладывается в несколько шагов:

  • пользователь открывает сайт;
  • запрос уходит не на VPS напрямую, а на ближайший к нему дата-центр Cloudflare;
  • если Cloudflare уже имеет копию запрошенного ресурса в своём edge-кэше, он отдаёт её сразу;
  • если кэша нет, Cloudflare идёт на origin-сервер (ваш VPS), забирает файл, сохраняет копию у себя и выдаёт пользователю;
  • повторные запросы обслуживаются с edge-узла, что снимает нагрузку с сервера и сокращает latency.

По сути Cloudflare работает как распределённый reverse proxy с кэширующим слоем. Для proxied-записей он может оптимизировать, кэшировать и защищать запросы к приложению. Главное, что от вас требуется — правильно настроить заголовки на origin и включить проксирование в DNS, остальное Cloudflare делает автоматически.

Важно понимать: это не волшебная таблетка. Если контент динамический, персонализированный или не имеет внятной стратегии кэширования, edge-слой будет часто промахиваться и нагрузка на VPS останется высокой. Схема оправдывает себя там, где есть стабильный пласт повторяющихся GET-запросов.

Когда такая схема оправдана

Вариант с VPS и Cloudflare отлично работает в типовых сценариях малого и среднего бизнеса, когда не хочется разворачивать полноценную CDN-инфраструктуру или платить за отдельный сервис. Вот когда он действительно выстреливает:

  • статический сайт или одностраничное приложение с большим количеством ассетов;
  • блог или документация, где много изображений, CSS и JavaScript;
  • раздача файлов — дистрибутивы, PDF, медиа;
  • небольшой проект на одном VPS, который уже не справляется с пиковым трафиком;
  • API или приложение, где можно кэшировать отдельные ответы без риска отдать чужие данные.

Ограничения тоже есть, и их лучше проговорить сразу. Не стоит ждать чудес, если:

  • контент меняется каждую секунду и плохо поддаётся кэшированию;
  • логика сайта завязана на персонализированных ответах (личные кабинеты, корзины);
  • все запросы требуют авторизации;
  • backend тяжёлый и динамический, а настроить cache headers не получается.

В таких случаях Cloudflare будет просто лишним звеном, добавляющим задержку, а не ускоряющим. Но если хотя бы половина трафика — это статика, выигрыш будет заметен практически сразу.

Из чего состоит простая схема

Компонент Роль Что важно
VPS Origin-сервер Отдаёт исходный контент
Cloudflare DNS Точка входа Управляет маршрутизацией домена
Proxied запись Включает проксирование Запросы идут через Cloudflare, а не напрямую на VPS
Cache Rules / заголовки Управляют кэшированием Определяют, что и на сколько хранить
TLS на Cloudflare и origin Безопасный канал Нужен корректный режим шифрования

Каждый элемент по отдельности прост, но именно их согласованность даёт рабочий результат. Например, можно включить проксирование, но если origin отдаёт Cache-Control: no-cache, Cloudflare будет каждый раз идти на сервер. Или наоборот: заголовки корректные, но DNS-запись работает в режиме DNS-only — тогда трафик вовсе не проходит через Cloudflare, и кэша нет.

Базовая логика работы Cloudflare с кэшем

Cloudflare не кэширует всё подряд — у него есть чёткие правила, основанные на HTTP-заголовках ответа. По умолчанию он не кэширует ресурс, если в ответе присутствуют:

  • Cache-Control: private;
  • Cache-Control: no-store;
  • Cache-Control: no-cache;
  • Cache-Control: max-age=0;
  • заголовок Set-Cookie;
  • метод запроса не GET.

Напротив, ресурс будет закэширован, если в ответе есть Cache-Control: public и max-age больше нуля, либо заголовок Expires с датой в будущем.

Это ключевой момент, который часто упускают: CDN на базе Cloudflare живёт не только в панели, но и в заголовках ответа. Если ваш веб-сервер не отдаёт корректные заголовки, Cloudflare будет действовать консервативно и не станет кэшировать. Поэтому настройка начинается с origin-сервера, а не с панели Cloudflare.

Дополнительно Cloudflare позволяет управлять поведением через Cache Rules, Edge Cache TTL и Browser Cache TTL. Но базовый принцип остаётся: заголовки origin — фундамент, правила в панели — надстройка.

Пошаговая настройка

1. Подготовьте VPS

Прежде чем подключать Cloudflare, убедитесь, что origin-сервер готов к роли backend для CDN. На VPS должны быть:

  • веб-сервер: Nginx, Apache или другой;
  • рабочий сайт;
  • открытые порты 80 и 443;
  • корректный SSL-сертификат на origin;
  • возможность отдавать статические файлы с правильными заголовками.

Минимально полезно сразу проверить:

  • отдаются ли Cache-Control;
  • не ломается ли сайт без прямого доступа по IP;
  • не завязаны ли ссылки на IP-адрес сервера;
  • корректно ли работает HTTPS на origin.

По опыту, частая проблема — когда сайт написан так, что все ссылки генерируются с IP вместо домена. После включения проксирования такие ссылки сломаются, потому что браузер будет пытаться обойти Cloudflare. Поэтому сначала проверьте, что сайт нормально работает по домену, а не только по IP.

2. Подключите домен к Cloudflare

Дальше стандартная процедура:

  • добавить домен в Cloudflare;
  • сменить NS у регистратора на выданные Cloudflare;
  • дождаться обновления DNS (обычно от нескольких минут до 48 часов);
  • создать A или CNAME-запись на VPS;
  • включить проксирование — то самое «оранжевое облако».

Именно проксирование включает прохождение трафика через Cloudflare. В режиме DNS-only Cloudflare работает как обычный DNS-сервер и не участвует в доставке контента. Не перепутайте: серая тучка — это просто DNS, оранжевая — полноценный прокси с кэшем и защитой.

3. Разделите записи по типам

Не все DNS-записи надо проксировать. Проксировать стоит только те, что относятся к веб-трафику:

  • A и AAAA для веб-сайта;
  • CNAME для основного хоста сайта.

Обычно не проксируют:

  • почтовые записи (MX, SPF, DKIM);
  • внутренние сервисы;
  • служебные поддомены, если они должны работать напрямую.

Проксирование почтовых записей сломает доставку писем, потому что Cloudflare не предназначен для SMTP-трафика. Поэтому всегда проверяйте, какие записи вы переключаете в оранжевый режим.

4. Настройте кэширование статики на VPS

Теперь главный шаг — научить origin-сервер отдавать правильные заголовки. Для статики обычно достаточно выставить долгий срок жизни кэша. Пример для Nginx:

location ~* \.(js|css|png|jpg|jpeg|gif|svg|woff2)$ {
    expires 30d;
    add_header Cache-Control "public, max-age=2592000";
    try_files $uri =404;
}

Для статики это даёт Cloudflare чёткий сигнал: «храни 30 дней и отдавай всем». Если файл меняется редко, можно добавить immutable и использовать версионирование имени файла, например app.4f2c1.js. Тогда даже при изменении контента старый кэш не станет проблемой — новый файл получит новое имя.

Для HTML и API-ответов заголовки должны быть более сдержанными: либо короткий TTL, либо вообще запрет кэширования, если контент персонализирован. Универсального рецепта нет, отталкивайтесь от характера данных.

5. Настройте правила в Cloudflare

После того как origin отдаёт корректные заголовки, можно точечно управлять поведением в панели Cloudflare. Имеет смысл:

  • включить кэширование статики (часто уже работает по умолчанию);
  • задать Cache Rules для HTML, если сайт это допускает;
  • проверить поведение по заголовкам;
  • не полагаться на «автоматическую магию» без теста.

Cloudflare Edge может отдать ответ из кэша напрямую, не обращаясь к Worker-коду, если используется Workers Cache; при попадании в кэш снижается задержка и расход CPU. Для обычного origin-сценария принцип похожий: cached response возвращается с edge, а при miss запрос идёт на origin. Главное — чтобы правила не конфликтовали с заголовками origin.

6. Проверьте результат

После включения проксирования и правил обязательно проверьте, что всё работает. Самый простой способ — команда:

curl -I https://example.com/image.png

Обратите внимание на заголовки вроде:

  • CF-Cache-Status;
  • Cache-Control;
  • Age;
  • Expires.

Типовые статусы Cloudflare:

  • HIT — файл отдан из кэша;
  • MISS — кэша не было, файл забрали с origin;
  • EXPIRED — кэш устарел, Cloudflare пошёл за свежей копией;
  • DYNAMIC — ресурс не кэшируется.

Если на повторный запрос вы видите MISS или DYNAMIC, значит что-то не так: либо заголовки origin запрещают кэширование, либо правила Cloudflare не позволяют хранить этот ресурс. Разбирайтесь с этого.

Что кэшировать в первую очередь

Тип контента Кэшировать Комментарий
CSS/JS Да Почти всегда выгодно
Изображения Да Один из лучших кандидатов
Шрифты Да Особенно если редко меняются
HTML статического сайта Да С коротким TTL или по правилам
HTML блога Иногда Нужна аккуратная стратегия инвалидации
API-ответы Осторожно Только если нет персонализации
Личный кабинет Нет Риск утечки данных

Статика — это хлеб CDN. CSS, JS, картинки, шрифты меняются редко, а запрашиваются часто, поэтому их кэширование даёт максимальный эффект. HTML уже сложнее: с одной стороны, хочется ускорить отдачу, с другой — есть риск отдать устаревшую разметку. Компромисс — короткий TTL или включение кэша только для публичных страниц без cookie.

Как сделать «простую CDN-схему» правильно

1. Версионируйте файлы

Если файл меняется, меняйте его имя. Варианты:

  • main.css?v=12 — рабочий вариант;
  • main.12ab34.css — лучше;
  • просто main.css — хуже.

Версионирование позволяет ставить длинный срок жизни кэша без страха сломать обновление. Браузер или Cloudflare будут считать новый файл новым ресурсом и не станут подтягивать старую версию из кэша.

2. Не кэшируйте всё подряд

Главная ошибка новичков — включить «кэшировать HTML везде» и потом долго ловить баги:

  • старые цены;
  • устаревшие заголовки;
  • не тот логин;
  • случайно закэшированные персональные страницы.

Кэш — это компромисс между скоростью и актуальностью. Если не уверены, начинайте с консервативных настроек и постепенно расширяйте.

3. Следите за Set-Cookie

Если ответ содержит Set-Cookie, Cloudflare по умолчанию не кэширует его. Это встроенная защита от грубых ошибок, но она не отменяет необходимости проверять логику приложения. Иногда cookie ставятся даже на статические запросы из-за особенностей фреймворка, и тогда Cloudflare будет игнорировать ваши заголовки Cache-Control.

4. Используйте короткий TTL для спорных страниц

Для новостей, карточек товаров и блога часто разумно:

  • держать HTML в кэше недолго (например, 60–300 секунд);
  • обновлять кэш после публикации;
  • использовать purge по URL или по тегам, если процесс выстроен.

Так вы получите ускорение на повторных запросах, но не рискуете показывать пользователю устаревший контент в течение длительного времени.

5. Не забывайте про HTTPS на origin

Проксирование через Cloudflare не отменяет требования к нормальному TLS на VPS. Если origin отдаёт самоподписанный сертификат или не настроен HTTPS, вы можете получить проблемы с режимом шифрования, ошибками соединения и неожиданными сбоями. Настройте SSL-сертификат на VPS (Let’s Encrypt — бесплатно и надёжно), а в Cloudflare выберите режим шифрования «Full» или «Full (strict)», чтобы трафик между Cloudflare и origin также шёл по HTTPS.

Практический сценарий для блога или малого сайта

Для типового блога на WordPress, статического сайта или небольшого интернет-магазина оптимальная схема обычно выглядит так:

  • Cloudflare проксирует основной домен (A/AAAA запись с оранжевым облаком);
  • статика кэшируется на 30 дней или больше (за счёт долгих max-age на origin и/или Cache Rules);
  • HTML кэшируется коротко (например, 60–300 секунд) или только для публичных страниц;
  • админка и служебные разделы обходят кэш (через Page Rules или Cache Rules, отключающие кэш для /wp-admin/ или /admin);
  • обновление контента сопровождается очисткой нужных URL через Cloudflare API или панель.

Такая конфигурация даёт заметный выигрыш без сложной архитектуры и без отдельного CDN-провайдера. Нагрузка на VPS падает в разы, потому что основная масса запросов к картинкам и скриптам обслуживается с edge-узлов Cloudflare, а origin получает только промахи кэша и динамические запросы.

Типовые ошибки

Вот что чаще всего идёт не так при настройке:

  • включить проксирование, но оставить ответы с Cache-Control: no-cache — Cloudflare не будет кэшировать;
  • забыть, что HTML не кэшируется так же просто, как картинки — нужна отдельная стратегия;
  • не настроить версионирование ассетов — тогда длинный кэш приведёт к тому, что пользователи будут долго видеть старые версии;
  • кэшировать страницы с Set-Cookie — Cloudflare сам не закэширует, но если настроить принудительно, можно получить утечку сессий;
  • ждать ускорения от Cloudflare, не проверив CF-Cache-Status — часто кэш просто не работает, а владелец сайта этого не замечает;
  • закрыть origin только частично и оставить прямой доступ к IP — тогда все преимущества Cloudflare можно обойти, а сервер будет получать нагрузку напрямую;
  • не продумать purge после обновления сайта — контент меняется, а CDN продолжает отдавать старьё.

Большинство этих проблем решаются внимательным чтением заголовков и тестированием на реальных URL.

Как понять, что схема работает

Проверяйте не ощущения, а метрики. Вот что должно измениться после корректной настройки:

  • CF-Cache-Status: HIT на статику при повторных запросах;
  • снижение количества запросов на VPS (видно в логах веб-сервера);
  • уменьшение времени ответа на повторных загрузках (TTFB для кэшированных ресурсов должно быть минимальным);
  • падение нагрузки на CPU и сеть origin-сервера;
  • более стабильная отдача в пиковые часы.

Если сайт стал «быстрее только первый раз», значит кэширование настроено не до конца. Скорее всего, статика всё ещё отдаётся с origin, либо Cloudflare не имеет права её кэшировать.

Когда нужен уже не «простой CDN», а больше

Обычной схемы на VPS и Cloudflare может не хватить, если:

  • у вас много географически распределённой аудитории и важна минимальная задержка в каждом регионе;
  • контент генерируется динамически и должен кэшироваться по сложным правилам (например, разные версии для разных стран);
  • нужна тонкая логика по странам, устройствам или языкам;
  • есть большие медиафайлы и высокий трафик, требующий оптимизации на edge;
  • требуются сложные edge-вычисления (обработка запросов ближе к пользователю).

В таких случаях на сцену выходят более продвинутые инструменты Cloudflare: Workers для выполнения кода на edge, tiered cache для снижения нагрузки на origin путём многоуровневого кэширования, а также собственная архитектура публикации контента. Tiered cache, в частности, позволяет региональным уровням кэша перехватывать повторные запросы до того, как они дойдут до origin-сервера, что особенно полезно при большом количестве edge-узлов.

Чек-лист перед запуском

  • Домен подключен к Cloudflare.
  • Основной веб-хост проксируется (оранжевое облако).
  • Почтовые и служебные записи не затронуты.
  • На VPS настроены HTTPS и корректные заголовки.
  • Для статики задан Cache-Control: public с длинным max-age.
  • Версионирование ассетов включено.
  • HTML проверен отдельно (короткий TTL или исключение админки).
  • Админка исключена из кэша.
  • Проверка curl -I показывает нужные заголовки и статус HIT на повторных запросах.
  • После правок есть понятный процесс очистки кэша (purge).

Если все пункты выполнены, можно запускать схему в бой и мониторить метрики в первые дни.

Вывод

Простой CDN на базе VPS и Cloudflare — это не попытка повторить архитектуру гигантов, а прагматичный способ быстро получить кэш на edge, снять часть нагрузки с сервера и ускорить доставку статики. В большинстве небольших и средних проектов такого решения достаточно, если правильно настроить DNS, заголовки, проксирование и исключения. Главный принцип прост: Cloudflare не заменяет архитектуру, а усиливает её там, где вы сами уже навели порядок. Без порядка на origin-сервере даже самый мощный CDN не поможет.

FAQ

Cloudflare сам по себе уже CDN?

Да, если домен включен в проксирование и контент кэшируется на edge. В режиме DNS-only Cloudflare работает просто как DNS-сервер, и никаких CDN-функций нет. Так что ключевой признак — оранжевое облако в DNS-записях.

Нужно ли покупать отдельный CDN?

Для малого и среднего сайта часто нет. Cloudflare закрывает базовые задачи кэширования, доставки и защиты, причём бесплатного тарифа обычно хватает. Отдельный CDN имеет смысл, когда появляются специфические требования: кастомная логика кэширования, продвинутая аналитика, гарантированный SLA.

Почему HTML не кэшируется так же легко, как картинки?

Потому что HTML чаще меняется и нередко зависит от cookie, авторизации и состояния пользователя. Cloudflare не кэширует ответ, если в нём есть Set-Cookie или запрещающие заголовки. Поэтому для HTML нужна отдельная стратегия: короткий TTL, исключение админки или полный отказ от кэширования.

Как проверить, что файл реально отдаётся из кэша?

Посмотреть CF-Cache-Status в заголовках ответа. Для повторных запросов к статикам нужен статус HIT. Если видите MISS или DYNAMIC, значит кэш не сработал — проверяйте заголовки origin и правила Cloudflare.

Можно ли кэшировать API?

Можно, но только если ответ одинаков для всех пользователей и не содержит персональных данных. Иначе это прямой риск утечки информации. Кэшировать API стоит через Cache Rules или Workers с учётом семантики конкретного endpoint’а.

Что важнее: настройки Cloudflare или заголовки на сервере?

Оба слоя важны. Cloudflare принимает решение о кэше на основе своих правил и заголовков ответа, поэтому без корректного origin-контроля схема работает плохо. Заголовки origin — это базовый уровень, а правила Cloudflare позволяют точечно скорректировать поведение. Начинайте с origin и затем добавляйте правила в панели.

Курилка дата-центра

Неформальное послесловие к разбору. Здесь без официоза: рекламные вставки вырезаны, остаётся разговор по существу — как у стойки с «железом».

без приукрашиваний