Комментарии 40
В данном примере make целиком бесполезная зависимость. Ничем не отличается от файлов в папке bin.
./bin/up
./bin/restart
./bin/psql
и тп.
эмм забавно конечно, но что мешает добавить все эти команды как alias в .bashrc / .zshrc?
В этом случае даже не нужно make писать. Если проектов много можно даже и так:
dc-<project>-up
dc-<project>-down
dc-<project>-build
Ну если процесс сборки очень хитрый с кастомными образами, кучей скриптов — то почему бы и нет, но ping + db так собирать это по моему перебор немного...
make build, make stop, make start -> знают как развернуть и поднять проект
Чтобы можно было включить его в репозиторий
Как по мне это как то не правильно
Вот есть человек, который привык к дефолтным ключам, а вы ему — не, запускай давай make.
Костыли.
Часто, в работе требуется выполнять разные команды с параметрами в зависимости от настроек конкретного окружения. Постоянно вспоминать команды — напрягает, хочется как-то это упростить и автоматизировать.
Это удобно использовать при переключении между ветками проекта: выполнить миграции, подтянуть новые зависимости или запустить установку заново.
Конечно же обертку можно написать на любом языке, но Make уже дает готовый инструмент.
Как пример, список команд в одном наших из проектов:
=== Application ===
make configure — Настройка конфигов
make reinstall — полная переустановка сервиса (сборка контейнера, сброс БД, composer install)
make install — первоначальная установка или обновление сервиса (сборка контейнера, composer install)
make status — статус приложения
make clean — удаление всех файлов, которые созданы во время установки
make cache-clear — прогрев кэша (через приложение)
=== Tests ===
make app-ok — проверка всего сервиса
make cc — прогон тестов
=== Docker ===
make up — поднять сервис
make stop — остановить сервис
make down — остановка с удалением контейнера
make php-cli — войти в shell сервиса php
make nginx-cli — войти в shell сервиса nginx
make php-log — stdout сервиса php
make nginx-log — stdout сервиса nginx
=== DB ===
make migrate — накатка миграций
make remigrate — Очистка БД и выполнение миграций
Нда, какой-то дикий изврат.
Совершенно согласен с предыдущими коментами, что проще это всё запихать в алиасы. Причём, не обязательно в .bashrc, а в любой другой файл, который может быть подключен через .bashrc.
Да и что мешает накатать банальный container_control.sh, для которого, как минимум, не надо знать синтаксиса make.
Грустнее этого может быть только запуск системного сервиса через samopalny_service.sh & при загрузке системы.
Вот программисты переживают за код, который будут разбирать другие после них, хотелось бы чтобы и админы переживали за конфигурацию серверов.
В наши дни сложно представить себе разработку новой программной системы без применения микросервисов. А эта ситуация, в свою очередь, ведёт нас к платформе Docker.
Ну не знаю. К платформе Докер нас ведёт, в первую очередь, то что не требуется настраивать инстансы каждый раз, а пользоваться имейджами. Ну и стопицот дополнительных плюшек.
А микросервисы так вообще спорная вещь…
упрощение работы с использованием Makefile
Это не упрощение. Это усложнение — лишний слой абстракции, скрывающий под капотом реальные аргументы команды. За это придется платить.
По сути, мысль можно свести к следующему: для удобства каждый разработчик должен завернуть все линуксовые команды [а чего на docker-compose то остановились? давайте make ls вместо ls -Altr] в свой удобный враппер, которым привык пользоваться.
C-программисты — в make, Java — в maven goal, JS — в scripts в package.json, а питонисты пусть для manage.py модули пишут.
Только вот под лишним слоем абстракции всегда теряется понимание внутренних процессов и во время траблшутинга наступает час расплаты.. Я уже это в мире Windows видел, где люди управляют серверами мышкой и не отдупляют, что у них вообще происходит.
Это не упрощение. Это усложнение — лишний слой абстракции, скрывающий под капотом реальные аргументы команды. За это придется платить.
Всё смешалось: люди, кони. Речь идёт о предоставлении единого интерфейса к разным сервисам — или упрощении интерфейса. Был ли упрощён интерфейс? Был.
Ценой чего был упрощён интерфейс? Верно, ценой абстракции — усложнения реализации
А вот мысль "За это придется платить." прошу пояснить: за годы работы в саппорте понял, что игра в угадайку — неблагодарное занятие
По сути, мысль можно свести к следующему...
По сути, так любую здравую мысль можно свести к абсурду. Гротеск такой гротеск.
C-программисты — в make, Java — в maven goal, JS — в scripts в package.json, а питонисты пусть для manage.py модули пишут.
Перевожу на русский язык: "я не знаю, зачем нужен make, maven, package.json и manage.py, но соберу в одну кучу и покажу, какой я дофига умный". Возможно, повезёт в следующий раз
Только вот под лишним слоем абстракции всегда теряется понимание внутренних процессов и во время траблшутинга наступает час расплаты… Я уже это в мире Windows видел, где люди управляют серверами мышкой и не отдупляют, что у них вообще происходит.
И снова всё смешалось. Абстракция не есть сокрытие реализации, и сравнение с Windows ошибочно.
А давайте откажемся от файловых систем — они скрывают реализацию хранения данных на носителях. Давайте к каждому носителю обращаться напрямую — ведь за слои абстракций над носителями приходится платить! Давайте обращаться к цилиндрам на HDD. К чёрту файловые системы — эти абстракции так легко рушатся, а при траблшутинге никто дупля не отрезает, что на самом деле происходит и где на самом деле данные хранятся на диске
Вы прослушали миниатюру "Гротеск". Или, может, не всё ли равно, как носители работают внутри, если нам важен интерфейс — хранилище?
Выводы:
- Абстракции не всегда есть "зло, за которое придётся платить"
- Абстракции хороши, будучи применёнными к месту и в нужном объёме
А вот мысль "За это придется платить." прошу пояснить
Поторопились вопрос задавать. Ниже по тому же тексту объяснено, чем платить — непониманием, куда двигаться во время траблшутинга.
По сути, так любую здравую мысль можно свести к абсурду
Вот тут вы точно ошибаетесь. Если мысль можно свести к абсурду, значит она и была неверна изначально. Правильную мысль свести к абсурду без нарушения логики не получится. Подробнее тут.
я не знаю, зачем нужен make, maven, package.json и manage.py, но соберу в одну кучу и покажу, какой я дофига умный
Опаньки, переход на личности пошел. Ну ок, правила игры усвоены.
Я знаю, зачем нужен make и все остальное перечисленное. И уверен, что знаю лучше вас ;-)
Если вы не знаете, что объединяет эти столь непохожие инструменты, то подтянуть знания надо вам, а не мне. Откройте пожалуйста package.json, убедитесь, что секция scripts — ни что иное, как алиасы к другим командам, о которых тут в комментах не написал только ленивый.
А давайте откажемся от файловых систем
Единственное, где согласен и где вопрос спорный.
Вы прослушали миниатюру "Гротеск"
Сразу после знакомства с package.json пожалуйста ознакомьтесь с термином "гротеск", который вы примеряете не по смыслу.
Забавно, но я недели полторы назад провел коллегам лекцию на тему использования build-tools на примере Make для похожих задач.
Вообще make не обязателен, можно использовать любую приблуду из списка софта для автоматизации сборки
У меня, например, Terraform в make завёрнут.
У одного из коллег деплой Kafka в k8s, причем мы пришли к такому решению независимо.
В статье не раскрыто в каком случае такая заморочка становится нужной.
Для меня это имеет простой и понятный смысл.
После выхода проекта из стадии активной разработки я Operations отдаю менее квалифицированным "условным индусам", которые разбираться в кишках проекта не станут и для них, что короткая строка команды, что длинная одинаково непонятны.
Но в короткой вероятность ошибки в разы ниже.
К тому-же у нас разворачиваются десятки однотипных сред, TF код построен таким образом, что отличие в значении пары переменных позволяет деплоить совсем другое окружение в неслольких географически разнесенных зонах.
Таким образом:
make apply PROJECT=blabla ENV=test APPROVE=yes
За счет chain commands превращается в:
terraform workspace select blabla_test && \
terraform fmt && \
terraform validate && \
terraform apply -lock=true -input=false -refresh=true -var project=blabla -var env=test -var-file=blabla_test.tfvars -auto-approve
Причем файл переменных подхватывается только если он существует и есть ешё пара несущественных (но приятных) плюшек.
Вроде того что у каждой среды есть свой независимый стейт.
Как это удобно и, в особенности, переносимо сделать на алиасах в Bash я не представляю.
Хотя алиасов и функций у меня в ~/.bashrc немало.
Теперь по тексту статьи, хочу автора немного пожурить.
Если используете самодокументируемые Makefile то нужно в них документацию добавлять.
На примере Makefile из статьи
build: ## Buids docker compose file in this directory
docker-compose -f docker-compose.yml build $(c)
Тогда make help
будет не только список команд выдавать, но и справку по ним.
Ах ты досада какая, зря я автора журил…
В статье обычный Makefile не самодокументируемый.
Тогда вот пример как добавить документацию в Makefile.
help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
build: ## Buids docker compose file in this directory
docker-compose -f docker-compose.yml build $(c)
Класс, спасибо за идею!
Вообще make не обязателен, можно использовать любую приблуду из списка софта для автоматизации сборки
Только make среди них самая распространённая, переносимая и простая. Да, после shell-скриптов непривычно, но, когда вникнешь, понимаешь весь дзен.
И help там есть из коробки, если добавлять к каждой команде description.
Интересно, спасибо, я его не находил, когда искал замену make. А можете поделиться нетривиальным примером использования из своей практики?
Ну просто какой-нибудь интересный пример его использования в твоих проектах.
Когда, в начале своей девопс-карьеры, увидел связку docker-compose + Makefile в соседнем проекте, вот так же, как большинство комментаторов тут плевался и обещал, что у меня никогда ничего такого не будет. А в итоге пришёл год спустя к тому же самому.
Разработчики, кстати, въехали моментально, вопросов почти не возникало. И то, что у всех наших проектов похожий интерфейс: make up|down|clean|shell|dbshell и т.п. — большой плюс.
Пробовал то же самое сделать в виде bash-скрипта — тоже вариант, но Makefile даже проще и компактнее. А алиасы слишком ограничены, и их, опять же, нужно в своём профиле прописывать.
Кстати, где-то читал, что .PHONY, в 99% случаев указывать вовсе не обязательно, что делает его ещё проще.
Начинал тоже с набора скриптов в директории ./bin
, но когда их стало больше 10 — начал искать альтернативу, и ей стал как раз Makefile
. Надо лишь чуть "въехать" в его синтаксис, и после этого дальнейшую разработку без него представить уже становится сложно.
Один из примеров того как можно его использовать можно найти тут (golang проект-болванка).
Ах да, ещё и документирование поддерживаемых целей возможна таким способом:
.DEFAULT_GOAL : help
# This will output the help for each task. thanks to https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
help: ## Show this help
@printf "\033[33m%s:\033[0m\n" 'Available commands'
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[32m%-14s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
К сожалению, он является дополнительной зависимостью, что должна быть на тачке каждого разработчика, а make
с 99% вероятностью уже стоит "по умолчанию".
Но yaml
читать многократно удобнее, тут спорить сложно. В сторону таскера посмотрю тоже обязательно, быть может зайдет созданием скрипта с именем ./task
с примерным содержанием docker run --rm -v "$(pwd):/rootfs" -w '/rootfs' task:image $@
Docker Compose: упрощение работы с использованием Makefile