Для ускорения быстродействия 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, изображения и текстовые файлы.
Бенчмарки
Для оценки работы сайта я используя расширение 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
- traefik.http.routers.blogs-knulst-https.tls.options=mintls12@file
- 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/$
- 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/$
- 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.
Читайте также:
- Как оркестровать микросервисы с помощью Docker Compose
- 6 принципов создания производительных веб-приложений
- Python FastAPI: OpenAPI, CRUD, PostgreSQL в Docker и внедрение зависимостей
Читайте нас в Telegram, VK и Дзен
Перевод статьи Paul Knulst: Use Varnish HTTP Cache and Docker To Boost Website Speed