Основы DevOps для фронтендера. Часть 2.

В прошлом посте я сделал очень много ошибок Killme Plzz https://smartprogress.do/user/171453 мне на них указал, за что ему огромное спасибо. Этот пост позволит исправить допущенные ошибки.

Итак, самая важная ошибка, я смешал в одном скрипте сборку(build) и развёртывание(deploy) приложения. Это очень разные процессы с массой нюансов.

Этап сборки

Основные нюансы сборки, что реально меняется достаточно мало файлов и библиотек в составе проекта, поэтому необходимо обязательно кеширование как Docker-контейнера, так и библиотек node_modules. Идеально уже подготовить контейнер, с уже скаченными и настроенными инструментами для сборки, но в моём примере, я кеширую только контейнер.

Далее, контейнеры собираются для разных целей: последняя сборка (later), текущая сборка, сборка для тестирования, стабильная сборка для пользователей (production). Для этого создаются разные ветки и\или теги. Например, тестировщики тестируют только сборку с тегом 1.1

Далее получившиеся контейнеры, необходимо хранить в реестре контейнеров (Сontainer Registry), чтобы можно было откатиться к нужному контейнеру, в этом реестре должны храниться не промежуточные контейнеры, которые создаются и уничтожаются в процессе сборки, а окончательные.

Вот мой код для сборки. Ну, не совсем мой я его взял из документации gitlab.

docker pull $CI_REGISTRY_IMAGE:latest || true – получаем последний(latest) контейнер

docker build --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latest . – собираем новый контейнер, на основе закешированного последнего и присваиваем ему теги хеша-сборки и последний(latest)

docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA – получившийся образа размещаем в реестре контейров

docker push $CI_REGISTRY_IMAGE:latest   

$CI_REGISTRY_IMAGE, $CI_COMMIT_SHA – это внутренние автоматические переменные gitlab, я думаю из названия ясно, что они делают.

У меня контейнер, получился размером 10Mбайт, можно ещё пооптимизировать, но я решил пока оставить как есть.

Этап размещения

Если серверов больше одного и ещё они для разных целей: тестирования, production и т.д. лучше использовать Ansible – это такой параллельный ssh. Но у меня сервер один, поэтому обойдусь bash.

Вроде всё просто, подключиться к удаленному серверу, оставить работающий контейнер, уничтожить его, скачать свежесозданный, запустить новый контейнер.

Но опять дьявол кроется в нюансах. Основной нюанс – это логи. Они имеют привычку разрастаться и пожирать всё свободное место.

У меня на прошлой работе тоже была проблема, комп завис и после перезагрузки не включался, оказалось места не было, всё было забито логами. Вроде очевидная ошибка, но ни в одной статье, что я использовал для подготовки, про неё не написали.

Есть 2 варианта решения проблемы с логами:

  1. использование log opts – переменные docker-контейра по управлению логами.
  2. либо использовать лог-драйвер journald, который сам будет вычищать лишнее

Т.к. контейнер у меня один поднимать службу логирования я большого смысла не вижу, поэтому выбрал первый вариант.

Вот получившийся код

«docker stop $(docker ps | grep mymoney | cut -d" " -f1) || true” остановить контейнер

«docker ps -a | grep 'mymoney' | awk '{print $1}' | xargs docker rm || true” удалить остановленный контейнер

«docker pull $CI_REGISTRY_IMAGE:latest» скачать свежий контейнер

«docker run --restart unless-stopped --log-opt max-size=50m --log-opt max-file=10 -p 80:80 -d registry.gitlab.com/orion55/mymoney:latest» запустить скаченный контейнер

Полный код файла .gitlab-ci.yml можно посмотреть здесь https://github.com/orion55/mymoney/blob/master/.gitlab-ci.yml

Основы DevOps для фронтендера. Часть 2.

Итак, какой вывод из всех моих упражнений в DevOps. Я перерыл уйму документации, видео. Информация в лучшем случае искажена, а худшем ложна. И как только проект чуть сложнее, чем «Привет мир!», все красивые руководства и видео, рушатся как карточный домик.

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

Оптимизировать я больше не буду, просто по факту это учебный проект, дальше копать и оптимизировать можно, но я не вижу смысла.

Наработанный опыт буду внедрять в следующих своих проектах.

Один комментарий к “Основы DevOps для фронтендера. Часть 2.”

Добавить комментарий