Налаштування Varnish для кешування Magento 2

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Налаштування Varnish для кешування Magento 2
Складна
~2-3 робочих дні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Налаштування Varnish для кешування Magento 2

Varnish — HTTP-акселератор, який працює перед веб-сервером. Для Magento 2 це стандартний production-стек: без нього сайт із 500+ одночасними відвідувачами входить у CPU-saturate на PHP-FPM. Magento 2 має вбудовану підтримку Varnish через ESI та X-Magento-Tags для інвалідації кешу.

Архітектура стека

Browser → Varnish :80/:443 → Nginx :8080 → PHP-FPM → MySQL/Redis
                         ↘ ESI requests (блоки корзини, авторизація)

Varnish слухає на 80/443, nginx перенесений на порт 8080 та приймає лише трафік від Varnish. Для SSL termination перед Varnish ставиться nginx або HAProxy на 443 з проксуванням на Varnish 80.

Установка Varnish

# Ubuntu 22.04
curl -s https://packagecloud.io/install/repositories/varnishcache/varnish74/script.deb.sh | sudo bash
apt install varnish

# Файл сервісу
systemctl edit varnish
[Service]
ExecStart=
ExecStart=/usr/sbin/varnishd \
  -a :80 \
  -T localhost:6082 \
  -f /etc/varnish/default.vcl \
  -s malloc,2g \
  -p thread_pools=2 \
  -p thread_pool_max=1000 \
  -p thread_pool_timeout=300

Розмір -s malloc,2g — для кешу Magento достатньо 2–4 GB. Менше 1 GB немає сенсу: Magento сторінки важать 80–200 KB і при малому кешу hit rate буде низький.

VCL-конфігурація для Magento 2

Magento 2 надає готовий VCL через admin: Stores > Configuration > Advanced > System > Full Page Cache > Varnish Configuration > Export VCL. Експортуємо та використовуємо як основу, але стандартний VCL вимагає правок.

Ключові частини VCL:

vcl 4.1;

import std;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
    .connect_timeout = 600s;
    .first_byte_timeout = 600s;
    .between_bytes_timeout = 600s;
}

acl purge {
    "localhost";
    "127.0.0.1";
}

sub vcl_recv {
    # Передаємо реальний IP
    if (req.restarts == 0) {
        if (req.http.X-Forwarded-For) {
            set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
        } else {
            set req.http.X-Forwarded-For = client.ip;
        }
    }

    # PURGE-запити від Magento
    if (req.method == "PURGE") {
        if (!client.ip ~ purge) {
            return (synth(405, "Not allowed"));
        }
        return (purge);
    }

    # BAN за X-Magento-Tags (інвалідація блоків)
    if (req.method == "BAN") {
        if (!client.ip ~ purge) {
            return (synth(405, "Not allowed"));
        }
        if (req.http.X-Magento-Tags-Pattern) {
            ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern);
        }
        return (synth(200, "Banned"));
    }

    # Не кешуємо HTTPS-індикатор
    if (req.http.X-Forwarded-Proto == "https") {
        set req.http.Ssl-Offloaded = "1";
    }

    # Не кешуємо cart, checkout, account
    if (req.url ~ "/(checkout|customer|account|cart|wishlist)") {
        return (pass);
    }

    # Видаляємо cookies на статичних ресурсах
    if (req.url ~ "\.(css|js|png|jpg|jpeg|webp|gif|ico|woff2|svg)(\?.*)?$") {
        unset req.http.Cookie;
        return (hash);
    }

    # Нормалізуємо Google Analytics параметри
    set req.url = regsuball(req.url, "(^|&)(utm_[a-z]+|gclid|gclsrc|fbclid)=[^&]*", "");
    set req.url = regsub(req.url, "^(.*)\?&?(.*)?$", "\1?\2");
    set req.url = regsub(req.url, "^(.*)\?$", "\1");

    return (hash);
}

sub vcl_hash {
    hash_data(req.url);
    if (req.http.host) {
        hash_data(req.http.host);
    } else {
        hash_data(server.ip);
    }

    # Різні кеши для HTTP/HTTPS
    if (req.http.Ssl-Offloaded) {
        hash_data(req.http.Ssl-Offloaded);
    }

    return (lookup);
}

sub vcl_backend_response {
    # Не кешуємо 5xx
    if (beresp.status >= 500) {
        set beresp.uncacheable = true;
        set beresp.ttl = 1s;
        return (deliver);
    }

    # TTL за типом контенту
    if (beresp.http.content-type ~ "text/html") {
        set beresp.ttl = 1d;
        set beresp.grace = 1h;
    }

    if (bereq.url ~ "\.(css|js|woff2)(\?.*)?$") {
        set beresp.ttl = 1y;
    }

    # Видаляємо cookies з кешованих відповідей
    if (beresp.ttl > 0s) {
        unset beresp.http.Set-Cookie;
    }

    return (deliver);
}

sub vcl_deliver {
    # Заголовки налагодження (вимкнути на prod)
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT";
        set resp.http.X-Cache-Hits = obj.hits;
    } else {
        set resp.http.X-Cache = "MISS";
    }

    # Видаляємо внутрішні заголовки Magento
    unset resp.http.X-Magento-Tags;
    unset resp.http.X-Powered-By;
    unset resp.http.Server;

    return (deliver);
}

Налаштування Magento 2

Admin > Stores > Configuration > Advanced > System > Full Page Cache:

  • Caching Application: Varnish Cache
  • TTL for public content: 86400 (24 години)

Admin > Stores > Configuration > Advanced > System > Full Page Cache > Varnish Configuration:

  • Access list: 127.0.0.1
  • Backend host: 127.0.0.1
  • Backend port: 8080

Вмикаємо FPC:

bin/magento cache:enable full_page
bin/magento config:set system/full_page_cache/caching_application 2
# 2 = Varnish, 1 = Magento built-in

ESI — динамічні блоки всередині кешованих сторінок

Magento 2 використовує ESI (Edge Side Includes) для персоналізованих блоків: корзина, ім'я користувача, wishlist. ESI вже вмикається в VCL через beresp.do_esi = true, який Magento встановлює у заголовку X-Esi: 1.

Перевірка, що ESI працює:

curl -I https://myshop.ru/ | grep X-Cache
# Повинен повернути: X-Cache: HIT

curl -I https://myshop.ru/checkout/cart/ | grep X-Cache
# Повинен повернути: X-Cache: MISS (корзина не кешується)

Інвалідація кешу

Magento інвалідує кеш автоматично при зміні товарів/категорій через BAN за тегами:

# Ручна інвалідація конкретної сторінки
curl -X PURGE http://127.0.0.1:80/catalog/product/view/id/42

# Інвалідація всього кешу
varnishadm "ban req.url ~ /"

# Статистика кешу
varnishstat -1 -f MAIN.cache_hit -f MAIN.cache_miss

Цільовий hit rate для Magento — 85–95%. Нижче 70% означає проблему: або занадто багато некешованих запитів, або VCL неправильно обробляє cookies.

Моніторинг

# Реальний час — запити та їхній статус
varnishlog -q 'RespHeader:X-Cache' -i RespHeader,ReqURL,RespStatus

# Топ некешованих URL
varnishlog -q 'RespHeader:X-Cache eq MISS' -i ReqURL | \
  awk '{print $2}' | sort | uniq -c | sort -rn | head -20

Nginx як SSL terminator

server {
    listen 443 ssl http2;
    server_name myshop.ru;

    ssl_certificate /etc/letsencrypt/live/myshop.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/myshop.ru/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:80;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header Ssl-Offloaded "1";
    }
}

Терміни

Установка Varnish, настройка VCL під Magento 2, перенесення nginx на 8080, настройка SSL termination: 1–2 дні. Тестування hit rate, інвалідації, ESI-блоків: 1 день. Нагрузочне тестування та фінальна настройка параметрів (malloc, thread_pools): 0.5–1 день.