В прошлом посте я сделал очень много ошибок 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 варианта решения проблемы с логами:
- использование log opts – переменные docker-контейра по управлению логами.
- либо использовать лог-драйвер 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. Я перерыл уйму документации, видео. Информация в лучшем случае искажена, а худшем ложна. И как только проект чуть сложнее, чем «Привет мир!», все красивые руководства и видео, рушатся как карточный домик.
Мне важно самому научиться искусству DevOps, и взял я вроде простой проект, по факту разместить статический сайт, предварительно его собрав из исходников. В результате получилось уйма геморроя и подробное внимание во многие внутренние процессы.
Оптимизировать я больше не буду, просто по факту это учебный проект, дальше копать и оптимизировать можно, но я не вижу смысла.
Наработанный опыт буду внедрять в следующих своих проектах.
Спасибо, изучим-)