Как ускорить сайт с помощью Varnish HTTP Cache и Docker

Для ускорения быстродействия Paul’s dev blog и повышения качества пользовательского опыта я решил попробовать интегрировать в свою среду Docker Swarm HTTP-кэширование.

Поизучав какое-то время тему и поспрашивав участников Reddit, которые, к сожалению, помочь мне не смогли, я все же нашел решение, которое отвечало моим ожиданиям.

В процессе его поиска я узнал о Varnish  —  ускорителе веб-приложений, также известном как обратный прокси c HTTP-кэшированием. Его можно установить перед любым сервером, использующим HTTP, для кэширования его содержимого. Он действительно очень быстрый и обычно ускоряет доставку пакетов в 300–1000 раз, уменьшает время загрузки и способен справляться с пиковыми нагрузками трафика.

В общем виде возможности Varnish показаны в этом видео:

Конфигурация

В моей новой конфигурации содержится сервер Varnish HTTP Cache, развернутый с использованием Docker в среде Docker Swarm. Размещается он между Traefik Proxy и блогом Ghost. В этой конфигурации Varnish используется для кэширования различного статического контента страницы, такого как JavaScript, CSS, изображения и текстовые файлы.

Сервис Ghost Blog с Traefik до и после использования Varnish HTTP Cache

Бенчмарки

Для оценки работы сайта я используя расширение Lighthouse от Google, giftofspeed.com и tools.pingdom.com. Все эти тестовые ресурсы загружают сайт так, будто процесс происходит в браузере. Я выполнил разные тесты из разных стран с включенным Varnish и без него. В результате я зафиксировал увеличение производительности примерно на 20%.

К примеру, протестировав один URL на giftofspeed.com несколько раз, я получил следующие результаты.

Без Varnish HTTP Cache:

С Varnish HTTP Cache:

Настройка

Для начала вам потребуется установить Docker и Docker Compose. Помимо этого, понадобится балансировщик нагрузки Traefik, который будет перенаправлять запросы в мой блог Ghost. Все правила (метки) в файле Compose будут основываться на моей установке Traefik.

Теперь, чтобы разместить Varnish между моим блогом Ghost и Traefik Proxy я расширяю файл Compose для этого блога (как это сделать, описано здесь (англ.)), сначала добавляя раздел varnish, а затем перемещая все метки из сервиса ghost в сервис varnish. После этого я меняю на сервере порт балансировщика нагрузки с 2368 (порт Ghost) на 80 (порт Varnish).

Еще одно необходимое изменение  —  это установка networks так, чтобы сервис ghost использовал только default, а сервис varnish использовал default и traefik-public. Последним изменением будет добавление конфигурации в файл Compose, содержащий настройки Varnish.

В итоге эта часть файла Compose будет выглядеть так:

varnish:
image: varnish:stable
container_name: varnish
restart: unless-stopped
configs:
- source: varnish_cfg
target: /etc/varnish/default.vcl
networks:
- default
- traefik-public
deploy:
labels:
- traefik.enable=true
- traefik.docker.network=traefik-public
- traefik.constraint-label=traefik-public
- traefik.http.routers.blogs-knulst-http.rule=Host(`www.knulst.de`) || Host(`knulst.de`) || Host(`blog.knulst.de`)
- traefik.http.routers.blogs-knulst-http.entrypoints=http
- traefik.http.routers.blogs-knulst-http.middlewares=https-redirect
- traefik.http.routers.blogs-knulst-https.rule=Host(`www.knulst.de`) || Host(`knulst.de`) || Host(`blog.knulst.de`)
- traefik.http.routers.blogs-knulst-https.entrypoints=https
- traefik.http.routers.blogs-knulst-https.tls=true
- traefik.http.routers.blogs-knulst-https.tls.certresolver=le
- [email protected]e
- traefik.http.services.blogs-knulst.loadbalancer.server.port=80
- traefik.http.middlewares.redirect-blogs-knulst.redirectregex.regex=^https://blog.knulst.de/(.*)
- traefik.http.middlewares.redirect-blogs-knulst.redirectregex.replacement=https://www.knulst.de/$${1}
- traefik.http.middlewares.redirect-blogs-knulst.redirectregex.permanent=true
- traefik.http.middlewares.redirect-blogs-knulst-nosub.redirectregex.regex=^https://knulst.de/(.*)
- traefik.http.middlewares.redirect-blogs-knulst-nosub.redirectregex.replacement=https://www.knulst.de/$${1}
- traefik.http.middlewares.redirect-blogs-knulst-nosub.redirectregex.permanent=true
- traefik.http.routers.blogs-knulst-https.middlewares=redirect-blogs-knulst, redirect-blogs-knulst-nosub
configs:
varnish_cfg:
file: ./default.vcl

В сервисе ghost мы определили конфигурацию, указывающую на default.vcl, который будет выглядеть так:

vcl 4.0;

backend default {
.host = "ghost:2368";
}
sub vcl_recv {
# Не кэшировать страницы admin и preview
if (req.url ~ "^/ghost($|/.*)" ||
req.url ~ "^/p($|/.*)" ||
req.url ~ "^/admin($|/.*)" ||
req.url == "/"
) {
return (pass);
}
if (req.url ~ "testclear") {
ban("req.http.host == knulst.de");
return(synth(200, "Cache was cleared by Rest call"));
}
}

В этом файле я объявил ряд особых правил для Varnish.

  • Установил backend на ghost:2368, поскольку во внутренней предустановленной сети ghost доступен через порт ghost:2368.
  • Удалил из кэша /ghost/…, /p/… и /admin/…, потому что меню админа не должно кэшироваться.
  • Удалил корневой URL этого блога, чтобы не сталкиваться с устаревшим списком заметок из-за кэширования.
  • Добавил URL (/testclear), чтобы можно было чистить кэш вручную.

Файл конфигурации Varnish я создал в одном каталоге с Docker Compose.

Теперь я мог развернуть полноценный файл Compose, чтобы у вас была возможность скачать его с GitHub Gist следующей командой:

$ docker stack deploy -c docker-compose.yml blog

Если вы захотите его использовать, обновите Host, базу данных (MySQL) и настройки почты.

Обработка ошибок

Подстройка конфигурации Varnish

Если я вдруг захочу изменить конфигурацию Varnish, то нужно будет обязательно изменить ее название, поскольку нельзя менять настройки в среде Docker. Можно без проблем изменить имя в файле Compose, развернуть его, а затем удалить старый ключ, чтобы переключаться между двух имен конфигурации.

После этого нужно будет заново загрузить ее, так как автоматически она не применится. Для этого я переключился на сервер, где развернут мой контейнер Varnish, и заново загрузил конфигурацию с помощью docker exec.

$ docker exec YOUR_VARNISH_CONTAINER varnishreload

Скачанные файлы не работают

Если вы слепо скачаете файл с GitHub Gist, то он не заработает, если не установить необходимые переменные для Mail, MySQL и Host. Загляните в это руководство (англ.), где объясняется настройка Ghost с помощью Docker. Дополнительно потребуется изменить настройки MySQL, поскольку данное руководство было написано до перехода на MySQL, и этой части в нем не хватает.

Заключение

Поздравляю! Если вы проследовали по моей инструкции, значит уже установили собственный блог на Ghost с Varnish HTTP Cache, который повысит его быстродействие.

Файл Compose целиком можно взять с GitHub Gist.

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи Paul Knulst: Use Varnish HTTP Cache and Docker To Boost Website Speed

Предыдущая статьяКак создать планировщик по управлению недвижимостью с помощью Bryntum и ванильного JavaScript
Следующая статьяКак собрать данные для DS-проекта с помощью Python: 3 шага