Introducción a ficheros Makefile con el que podrás automatizar comandos y ser más ágiles en la gestión de tus proyectos.
Este recurso se ha diseñado como una guía práctica de introducción a ficheros Makefile donde se podrá...
- Comprender los conceptos básicos de los ficheros Makefile.
- Crear y usar ficheros Makefile para automatizar tareas.
Esta formación está orientada principalmente a desarrolladores/as de software que deseen adentrarse en la cultura DevOps/GitOps y quieran ser más ágiles en su operativa diaria.
La metodología de esta guía se basa en:
- Teoría y conceptos, con explicaciones claras y concisas de los puntos clave.
- Demostraciones, con ejemplos reales y cotidianos.
Para aprovechar al máximo este recurso se necesita:
- Un equipo con acceso a Internet.
- Privilegios de administrador para instalar software.
- Conocimientos básicos de desarrollo web.
Un fichero Makefile es un archivo de texto que permite agrupar comandos en pasos (llamados targets) y ejecutarlos mediante un comando fácil de recordar.
Para procesar los ficheros Makefile se utiliza la herramienta make, que permite validar el Makefile y ejecutar los pasos en el órden que hayamos definido.
Los ficheros Makefile tienen una identación basada en tabuladores.
Un Makefile está compuesto por:
- Reglas
- Definen qué comandos ejecutar así como las dependencias de los mismos.
- Variables
- Guardan valores reutilizables como nombres de archivos o flags de compilación.
- Comentarios
- Empiezan con # y sirven para documentar el archivo.
Primero debemos crear un fichero Makefile
Y añadimos el siguiente contenido:
.DEFAULT_GOAL := main
CLEAR = clear
HOST_USER_ID := $(shell id --user)
# Esto es un comentario
.PHONY: limpiar-terminal
limpiar-terminal:
@$(CLEAR)
# Esto es un comentario
.PHONY: cual-es-mi-usuario
cual-es-mi-usuario:
@echo "Este es tu ID de usuario"
@echo $(HOST_USER_ID)
# Este es el comando principal
.PHONY: main
main: limpiar-terminal cual-es-mi-usuario
@echo "That's all falks!"
Una vez guardado, ejecutamos el comando make de la siguiente manera:
Sin especificar target
Especificando el target
Ambos comandos son equivalentes ya que, tal y como hemos definido en la línea 1 del Makefile, si no se especifica ningún target se usará el main por defecto.
En la línea 17 podemos ver que el target se define como main: limpiar-terminal cual-es-mi-usuario. Esto permite que, cada vez que ejecutemos el target main, primero se ejecute limpiar-terminal, luego se ejecute cual-es-mi-usuario y por último los comandos definidos en el propio target. Que, en este ejemplo, es un @echo "That's all falks!"
Hasta aquí puede parecer que los ficheros Makefile pueden no ser del todo útiles, pero veamos un caso de uso real.
Cuando trabajamos con aplicaciones dockerizadas (si no sabes de lo que hablo, aquí tienes una Introducción a Docker) tenemos que ejecutar prácticamente los mismos comandos una y otra vez pero hay algunos que son comunes a prácticamente todos los proyectos dockerizados:
- Construir la imágen
- Cuando trabajamos con imágenes Docker personalizadas debemos construir las imágenes antes de poder usarlas.
- Levantar la infraestructura
- Una vez construídas las imágenes, ya podemos levantar la infraestructura de nuestra aplicación.
- Reiniciar algún contenedor
- A veces es necesario reiniciar uno o varios contenedores para, por ejemplo, comprobar la estabilidad de nuestra infraestructura.
- Tumbar la infraestructura
- Cuando ya no necesitemos de dicha infraestructura la paramos y apagamos para que no siga consumiendo recursos innecesariamente.
- Acceder a un contenedor via shell
- En fase de depuración es bastante frecuente la necesidad de acceder mediante una terminal shell a un contenedor y navegar por su sistema de archivos...
- Ver los logs
- O bien, ver qué trazas y logs está volcando ese contenedor.
Estos son algunos pasos que siempre se necesitan cuando dockerizamos una aplicación por lo que, en vez de memorizar todos los comandos y sus opciones, uso un fichero Makefile que me permita automatizar estos comandos mediante steps sencillos, como por ejemplo:
.DEFAULT_GOAL := help
HOST_USER_ID := $(shell id --user)
HOST_USER_NAME := $(shell id --user --name)
HOST_GROUP_ID := $(shell id --group)
HOST_GROUP_NAME := $(shell id --group --name)
DOCKER_BUILD_ARGUMENTS = --build-arg="HOST_USER_ID=$(HOST_USER_ID)" --build-arg="HOST_USER_NAME=$(HOST_USER_NAME)" --build-arg="HOST_GROUP_ID=$(HOST_GROUP_ID)" --build-arg="HOST_GROUP_NAME=$(HOST_GROUP_NAME)"
# DOCKER RELATED
.PHONY: build
build:
@docker compose build $(DOCKER_BUILD_ARGUMENTS)
.PHONY: up
up:
@docker compose up --remove-orphans --detach
.PHONY: down
down:
@docker compose down --remove-orphans
.PHONY: restart
restart:
@docker compose restart
.PHONY: logs
logs:
@docker compose logs -f
.PHONY: shell
shell:
@docker compose app sh
De este modo para interactuar con la infraestructura de mis proyectos me basta con ejecutar los siguientes comandos:
Equivalencias usando ficheros Makefile
Step |
Comando |
make build |
docker compose build --build-arg=... |
make up |
docker compose up --remove-orphans --detatch |
make down |
docker compose down --remove-orphans |
make logs |
docker compose logs |
... |
... |
Puedes descargar una plantilla para ficheros Makefile que puedes personalizar a tu gusto 😁
Para ver los comandos disponibles simplemente ejecuta el siguiente comando:
╔════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ ║
║ .: AVAILABLE COMMANDS :. ║
║ ║
╚════════════════════════════════════════════════════════════════════════════════════════════════════════╝
· SERVICE(s) ... service1 servic2 ... serviceN
· USER ......... (1000) alcidesramos
· GROUP ........ (1000) alcidesramos
· build Docker: builds the service
· up Docker: starts the service
· restart Docker: restarts the service
· down Docker: stops the service
· logs Docker: exposes the service logs
· shell Docker: establish a shell session into main container
· health Docker: inspect the health for specific service
· init Application: initializes the application
Puedes profundizar en la creación y personalización de ficheros Makefile en Learn Makefiles with the tastiest examples, un gran recurso lleno de ejemplos y casuísticas.