Docker Build and Push Makefile
Create a Makefile for Docker workflows: building images, tagging with git SHA, pushing to registries, running containers, and multi-stage build targets.
Detailed Explanation
Docker Automation with Make
Docker commands are verbose and repetitive. A Makefile standardizes image names, tags, and registry paths, reducing errors and making CI/CD pipelines simpler.
Version Tagging
IMAGE_NAME ?= myapp
REGISTRY ?= docker.io/myorg
GIT_SHA := $(shell git rev-parse --short HEAD)
GIT_TAG := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
IMAGE_TAG ?= $(GIT_TAG)
FULL_IMAGE = $(REGISTRY)/$(IMAGE_NAME):$(IMAGE_TAG)
LATEST = $(REGISTRY)/$(IMAGE_NAME):latest
Using git SHA and tags for Docker image versioning creates traceability between code commits and deployed images. The ?= operator allows CI systems to override the tag: make push IMAGE_TAG=v1.2.3.
Build Targets
build:
docker build \
--build-arg GIT_SHA=$(GIT_SHA) \
--build-arg BUILD_TIME=$(shell date -u +%Y-%m-%dT%H:%M:%SZ) \
-t $(FULL_IMAGE) \
-t $(LATEST) \
-f Dockerfile .
build-no-cache:
docker build --no-cache -t $(FULL_IMAGE) -f Dockerfile .
Build arguments inject metadata into the image. The multi-line command uses backslash continuation for readability.
Push and Deploy
push: build
docker push $(FULL_IMAGE)
docker push $(LATEST)
run:
docker run --rm -it -p 8080:8080 $(FULL_IMAGE)
stop:
docker stop $$(docker ps -q --filter ancestor=$(FULL_IMAGE)) 2>/dev/null || true
Note the $$ in the stop target — this escapes the dollar sign so Make passes $(...)) to the shell for command substitution instead of trying to expand it as a Make variable.
Multi-Platform Builds
build-multi:
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t $(FULL_IMAGE) \
--push .
Docker Buildx supports multi-architecture images. The --push flag pushes directly after building.
Key Points
- Always tag with both a specific version and
latest - Use
--build-argto inject build metadata without modifying the Dockerfile - The
|| truepattern prevents Make from failing when no containers are running
Use Case
Managing Docker image builds for a microservice, including automated tagging from git, pushing to a container registry, and running containers locally for testing.