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.

Docker

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-arg to inject build metadata without modifying the Dockerfile
  • The || true pattern 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.

Try It — Makefile Generator

Open full tool