Как стать автором
Обновить

Комментарии 40

В данном примере make целиком бесполезная зависимость. Ничем не отличается от файлов в папке bin.
./bin/up
./bin/restart
./bin/psql
и тп.

Я тоже использую make для docker-compose, но у меня в Makefile еще прописаны зависимости, что помогает в работе за счет экономии мозговой энергии.

эмм забавно конечно, но что мешает добавить все эти команды как alias в .bashrc / .zshrc?
В этом случае даже не нужно make писать. Если проектов много можно даже и так:


dc-<project>-up
dc-<project>-down
dc-<project>-build
Ничего не мешает. Но Makefile можно положить в репозиторий, например, рядом с docker-compose.yaml и всё будет работать у всех разработчиков без каких либо дополнительных действий.
Ну и в Makefile можно прописать зависимости от Docker файлов и других, и тогда нужно будет меньше думать при пересборке имиджей.

Ну если процесс сборки очень хитрый с кастомными образами, кучей скриптов — то почему бы и нет, но ping + db так собирать это по моему перебор немного...

плюсом ко всему выше будет то, что make — довольно распространенная в индустрии утилита — новые разработчики, придя на проект, уже ожидают стандартные
make build, make stop, make start -> знают как развернуть и поднять проект

Это от проекта зависит. На php, js/ts, например, makefile точно редкий гость. Или баш-скрипты, или composer/npm/yarn или их комбинация. Иногда какой-нибудь таск-раннер на родном для проекта языке.

Чтобы можно было включить его в репозиторий

Можно использовать direnv и добавлять папку с скриптами в PATH при cd в папку проекта. И в репозиторий совать удобно, и окружение остальное не затрагивает.
Таже автозапуск nix-shell поддерживает, который может docker-compose подтянуть и вот это вот всё.
И много людей используют Makefile как алиасы для команд?
Как по мне это как то не правильно
В опенсорс проектах для установки и удаления — очень много.
Строго говоря, алиасы для команд это вся суть Makefile. Даже если учитывать команды для компиляции и сборки бинарников, в типичном Makefile почти всегда алиасы общего назначения (PHONY).
make install классический пример.
Главная фича Make, отслеживание изменённий в зависимостях здесь не используется. Всё тоже самое можно сделать с помощью обычного Баш скрипта со свитчем команд. Было бы даже по красивее. Синтаксис Make файлов мягко говоря не инуитивный.
Выглядит, как дичь. Можно еще один уровень абстракции сделать в на py/go/..., чтобы дергать make, чтобы дергать docker-compose. Странный подход.
Вот есть человек, который привык к дефолтным ключам, а вы ему — не, запускай давай 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 & при загрузке системы.
Вот программисты переживают за код, который будут разбирать другие после них, хотелось бы чтобы и админы переживали за конфигурацию серверов.

Когда проектов много, в альясах или шелл скриптах утонешь. Лучше, чтобы все было в проекте. В Makefile можно сделать зависимости на докерфайлы, файлы конфигурации и т.д.
Поверьте старому линуксоводу, это — лючше.
В наши дни сложно представить себе разработку новой программной системы без применения микросервисов. А эта ситуация, в свою очередь, ведёт нас к платформе 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-скриптов непривычно, но, когда вникнешь, понимаешь весь дзен.

Насчёт простой это очень спорно, особенно если шелл-скриптов не писал никогда. Да и сейчас встретить человекапрограммиста, никогда не слышавшего о нём вообще, куда проще, чем того, кто его хотя бы читает свободно

Главное не забыть это все завернуть в контейнер и покрыть еще одним docker-compose.
Больше бойлерплейта ради бога бойлерплейта
Давно использую taskfile.dev — выглядит проще и понятней, особенно учитывая что львиная часть функционала в Make нужна только многоэтапной ленивой компиляции программ на языках вроде C/C++.
И help там есть из коробки, если добавлять к каждой команде description.

Интересно, спасибо, я его не находил, когда искал замену make. А можете поделиться нетривиальным примером использования из своей практики?

tagirb Что ты понимаешь под нетривиальным примером? Если зависимости одних тасков от других — то taskfile.dev/#/usage?id=task-dependencies, если динамические параметры то taskfile.dev/#/usage?id=dynamic-variables

Ну просто какой-нибудь интересный пример его использования в твоих проектах.

tagirb Ну у меня в основном тривиальные примеры вроде github.com/risentveber/codility-lessons/blob/master/Taskfile.yml где я использую команды скорее как alias к длинным командам — в текущей статье такой же подход

То, что нужно, спасибо!

НЛО прилетело и опубликовало эту надпись здесь

Когда, в начале своей девопс-карьеры, увидел связку 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)

image

Выше уже советовали Task. Он тоже умеет выводить список задач и конфиг у него в привычном Yaml формате.

К сожалению, он является дополнительной зависимостью, что должна быть на тачке каждого разработчика, а make с 99% вероятностью уже стоит "по умолчанию".


Но yaml читать многократно удобнее, тут спорить сложно. В сторону таскера посмотрю тоже обязательно, быть может зайдет созданием скрипта с именем ./task с примерным содержанием docker run --rm -v "$(pwd):/rootfs" -w '/rootfs' task:image $@

Зарегистрируйтесь на Хабре, чтобы оставить комментарий