Продолжая документировать всё важное, что происходит под капотом этого сайта, рассказываю как летом переделал систему деплоя с хорошо масштабируемой за много денег, до почти не масштабируемой зато бесплатной. Попутно повысив скорость деплоя в 30 раз.
1 Дополнительный домен для проверки работоспособности с отдельным окружением.
Напоминаю, что последние несколько лет сайт собирался и деплоился на сервер через Github Actions. Имел «зеркало»1 и несколько слоёв защиты от дурака, которая не позволяла закоммитить что-то в неправильную ветку, или выложить криво собранный сайт в прод. Всё это было гвоздями прибито к git workflow поэтому на каждый деплой существовал собственный коммит.
Невозможно в этому году удержаться от шуток про хомяка. Олдфаги не помнят, ньюфаги не знают, но на заре рунета «хомяком» было принято называть домашнюю страничку, хоумпейдж. Все мои заметки про хомяка на самом деле об этом сайте.
2 Если вы все такие умные, придумайте заодно русский аналог слова commitment. В остальном: в технической заметке будет много англицизмов.
Разбираться и настраивать весь этот кошмар в 2019 году было интересно, но получившаяся в результате система была сильно overengineered2 для маленького статичного сайта. Мне кажется что такой продвинутый деплой до сих пор не каждый энтерпрайз использует.
К лету 2024 мне стало казаться, что оптимизировать кучу картинок на серверах Гитхаба, гоняя их между несколькими изолированными контейнерами чтобы потом вылить результат на VPS это совсем уж свинство от которого разумно было бы отказаться пока Грета Тунберг не посадила меня на нож.
Кроме того: в зависимости от настроений Гитхаба весь процесс мог занимать от 12 до 30 минут для сайта размером 1 Гб.
Что, в сущности, не страшно, ведь я никак не участвую в автоматизированной сборке, но сама мысль что такая тривиальная работа съедает так много времени в чужой инфре царапала сознание.
А ещё: из-за того что вся разработка велась локально необходимо было поддерживать окружение со всеми этими всратыми зависимостями Ruby и NodeJS.
Дошло до того, что занимавшийся вёрсткой Гриша, который не пользовался частью моих велосипедов, просто набросал себе альтернативную систему локальной сборки.
Последней каплей стал сломавшийся деплой: В какой-то момент на сервере просто закончилось место, а rsync мне об этом не просигналил. В итоге в прод ушёл сайт лишь с частью картинок. К счастью, благодаря симлинкам и бэкапам исправить такое можно быстро и без картинок он провисел лишь несколько минут.
В общем: я решил, что пришло время аншиппинга фич и что пора отрезать от системы деплоя всё, что нам не нужно и слезать с чужой инфры.
Разрабатываем и пишем контент прямо внутри контейнера
За последние несколько лет программисты добавили технологиям виртуализации ещё несколько уровней абстракции. В Ansible и Terraform вообще скоро добавят мобильные приложения для домохозяинов с микротранзакциями и блокчейном. А для работы с Docker больше не нужно жить в терминале, постоянно подглядывая в шпаргалку чтобы вспомнить с каким ключом запускать контейнер, чтобы после выхода он самоуничтожался.
Помимо Docker Desktop я был сильно впечатлён расширением Dev Containers для любимого VSCode, и которое позволяет любой проект открыть в контейнере не заморачиваясь с монтированием папок и пробрасыванием портов. Оно само работает из коробки. Я не знаю как. Отстаньте, я домохозяин.
3 Сборку которого нужно провести лишь раз на новой машине. Т.е. в моём случае примерно 1 раз в 5 лет.
Я набросал Dockerfile на базе ванильной Ubuntu, в которую устанавливается всё необходимое включая Node и Ruby. И теперь даже при отсутствии нужного образа3 на локальной машине, Dev Containers при первом старте предложит его собрать. Это занимает от 6 до 10 минут.
Времени за которое раньше можно было собрать и задеплоить сайт теперь достаточно чтобы собрать Docker образ и уже из него собрать и задеплоить сайт.
Итоговый образ весит порядка 900 Мб и там точно есть что оптимизировать, но сейчас его размер не выглядит для меня какой-то важной метрикой. Я даже не стал заливать этот образ в Docker Hub — на столько быстро он собирается даже на моём стареньком макбуке.
Закоммитил lock-файлы и забыл про локальную поддержку зависимостей и окружения. Даже удалил с хостовой машины NodeJS, Ruby и все эти rvm, rbenv, которые управляют десятками их версий. Теперь от покупки нового компьютера, или переустановки операционки до начала разработки нас отделяет 10 мин пока клонируются репозитории и собираются образы.
Собираем и деплоим с личных машин
Следующее, что пошло под нож — GitHub Actions. Теперь мы деплоим из того же контейнера, в котором разрабатываем и пишем контент. Прямо как наши деды.
4 Во многом потому, что он и так использовался для схожих задач этого сайта прежде.
Оркестратором сборки и деплоя стал Gulp4 . Если вам кажется, что Gulp это какое-то говно мамонта во времена когда все модники используют Vite и Webpack, то, наверное, вы правы. Однако, Gulp жив и обновляется и вокруг него построено сообщество.
Удивительно как вэб-технологии стремительно развиваются и как одновременно это не оказывает никакого влияния на сам вэб, который кривой, медленный, а большинство сайтов до сих пор рендерятся с ошибками.
Итак: нам не нужен стерильно-чистый контейнер, чтобы собирать и деплоить на stage и в prod. Всё, что нам нужно — несколько bash-скриптов и десяток gulp.task, которые удобно выстраиваются в пайплайны. При этом если стерильно-чистый контейнер всё-таки зачем-то понадобился, его всегда можно запустить из чистого образа Docker.
![Deploy architecture](/assets/posts_data/2024-07-22-snnkv-to-docker/deploy-arch.jpg)
Всё, для чего нам был необходим GitHub Actions теперь выполняется в одном локальном контейнере, вместо пяти облачных. И этот один, по сравнению с облачными ещё и ресурсами железа не ограничен.
Остальное по мелочи
Раньше, я хранил на VPS 5 последних версий каждого сайта и кэши к ним. В сумме это в 12 раз больше, чем весит один сайт. Теперь храню лишь последние 3 версии и будто бы даже это избыточно.
Во время переезда в контейнеры, который занял две недели, пришлось переписать и отрефакторить много кода: в основном серверный JS, но под нож попали так же все bash-скрипты. Количество файлов сильно сократилось.
Необходимость в телеграм-ботах для уведомлений, которые я активно использовал во времена когда сборка сайта занимала минуты, отпала сама собой. Теперь все этапы деплоя я вижу прямо в терминале.
Результаты
5 В какой-то момент я понял, что при помощи Gulp можно одновременно собирать статику и варить картинки, что высвободило ещё 15 секунд на сборке.
Весь сайт с оптимизированными картинками на сегодняшний день весит примерно
Метод | Сборка статики | Оптимизация графики | Доставка, бекапы, пре/пост проверки | Всего |
---|---|---|---|---|
Github Actions, очищенный кэш на VPS | 1 мин | 4 мин | ||
Github Actions с кэшированием | 1 мин | 4 мин | 7 мин | 12 мин |
Локальный контейнер, очищенный кэш | 15 сек | 40 сек | 3 мин | 4 мин |
Локальный контейнер с кэшированием | 15 сек | 40 сек | 10 сек | 50 сек |
Дело не в том, что Actions какие-то плохие. Заплати я деньги за гарантированное время, можно было бы жить на моей прошлой системе до конца веков. Сайт бы собирался и деплоился одинаков долго и надёжно при размере в 1 Гб и в 50 Гб. Можно было бы бесконечно подключать разработчиков и авторов к репозиторию раздавая им гранулированные права, а каждый билд логгировался бы до самого крошечного варнинга. Если бы я хотел стать SRE или девопсом, то показывал бы прошлую версию репозитория на собесах со словами «смотри чё могу».
Но зачем это всё, когда нужно просто собрать статику, оптимизировать графику и залить результат на VPS?
Сильно выросла переносимость. Если мне понадобится дать кому-то погонять этот «движок», написать статью, или починить дизайн/вёрстку, то я просто дам этому человеку доступ к репозиторию. С инструкцией из readme.md, которая состоит из 5 шагов, он сможет развернуть этот сайт локально меньше чем за 10 минут не думая о том, что под капотом там вообще есть какой-то Ruby, Gulp, или NodeJS.
Я просто ворую из интернета мемы про деплой хомяка.
6 Впрочем, можно попробовать git hooks.
Из очевидных минусов: процесс деплоя теперь не прибит гвоздями к git workflow6, как это было в GitHub Actions. Т.е. в теории дурак может постараться и наделать глупостей. Вот только дураков в окрестностях этого репозитория нет.
Поживём пока с контейнерами и, может, через пару лет сделаем какие-то выводы и переедем на что-то ещё более простое. Уверяю вас: рано или поздно всё закончится в GitHub Pages, а может даже на narod.ru.
⚠️ Каменты в режиме эксперимента. Нужна регистрация на GitHub и необходимо дать разрешение боту Giscus. Если это неприемлемо, можно комментировать прямо на GitHub.