Docker + Makefile
-
Comments:
- here.
I rewrote one of my projects (Fronius Dashboard) in Python - more because I was no longer able to get the build to work correctly under Elixir. As a side-effect, the image size went down a lot.
Part of this process is to build multiple-architectures, and publish these manifests. As an aside, being able to version them is also nice.
We’ll start with the versioning, because that’s a bit simpler.
Take a file VERSION
. Put the current version into this file (x.y.z
format is the only one supported so far).
Now, we can have a few tools to handle this:
.PHONY: bump-major bump-minor
requirements.txt: poetry.lock pyproject.toml
poetry export -o requirements.txt
bump-major:
cat VERSION | awk -F. '{print $$1 + 1 ".0.0"}' | tee VERSION
bump-minor:
cat VERSION | awk -F. '{print $$1 "." $$2 + 1 ".0"}' | tee VERSION
VERSION: app.py requirements.txt
cat VERSION | awk -F. '{print $$1 "." $$2 "." $$3 + 1}' | tee VERSION
This allows us to have make bump-major
that adds one to the existing major version, and resets the minor and patch versions. And another version that adds one to the minor version, and resets the patch version.
There is no bump-patch
, instead every file that could possibly affect the code is included in the make VERSION
dependencies list. This means that make VERSION
will only run if any files have changed, and in that case it will increment the patch version.
So, that’s the versioning. How about publishing docker images?
There are a couple of things that we need to do:
- build for a number of platforms (amd64, armv6 and armv7, because I run stuff on Raspberry Pi hardware).
- create and push a manifest of all images
- also create and push a tagged version (ie, not just latest).
IMAGE := <image-name-goes-here>
.PHONY: release bump-major bump-minor
release: Dockerfile VERSION
docker buildx build . -t $(IMAGE):armv6 --platform linux/arm/v6 --push
docker buildx build . -t $(IMAGE):armv7 --platform linux/arm/v7 --push
docker buildx build . -t $(IMAGE):amd64 --platform linux/amd64 --push
docker pull $(IMAGE):armv6
docker pull $(IMAGE):armv7
docker pull $(IMAGE):amd64
docker image rm --force $(IMAGE):latest
docker manifest create $(IMAGE):latest \
$(IMAGE):armv6 \
$(IMAGE):armv7 \
$(IMAGE):amd64 \
--amend
docker manifest annotate $(IMAGE):latest $(IMAGE):armv6 --variant v6l
docker manifest annotate $(IMAGE):latest $(IMAGE):armv7 --variant v7l
docker manifest create $(IMAGE):$(shell cat VERSION) \
$(IMAGE):armv6 \
$(IMAGE):armv7 \
$(IMAGE):amd64 \
--amend
docker manifest annotate $(IMAGE):$(shell cat VERSION) $(IMAGE):armv6 --variant v6l
docker manifest annotate $(IMAGE):$(shell cat VERSION) $(IMAGE):armv7 --variant v7l
docker manifest push $(IMAGE):$(shell cat VERSION)
docker manifest push $(IMAGE):latest
requirements.txt: poetry.lock pyproject.toml
poetry export -o requirements.txt
bump-major:
cat VERSION | awk -F. '{print $$1 + 1 ".0.0"}' | tee VERSION
bump-minor:
cat VERSION | awk -F. '{print $$1 "." $$2 + 1 ".0"}' | tee VERSION
VERSION: app.py requirements.txt
cat VERSION | awk -F. '{print $$1 "." $$2 "." $$3 + 1}' | tee VERSION
There is a bit of repetition - I’m sure I could do something using Makefile expansion, but this works for now.