DEV Community

flpslv
flpslv

Posted on

Using Makefiles to build and publish (docker) containers

Alt Text

There are more things in make and dockerfiles, Horatio,
Than are explained of in your documentation.

Intro

First of all, let's start this brief train of thought by acknowledging that despite docker is a synonym of containers, the other way around isn't true.

We could dwell on the origins of containers, but there are tons of much more valid articles out there than anything I could begin to try to explain here.

I'm assuming that containers, docker and dockerfiles aren't new terms for anyone reading this, but if that's the case then you can probably start by checking containers, docker and [dockerfile].(https://docs.docker.com/engine/reference/builder/)

Motivation

Usually, when I'm writing a dockerfile to ensure I'll never forget the needed steps to successfully build this or that container I always find myself looking at all those hardcoded version numbers and other things that could really fit in the definition of variables but for some reason end up for (commit&push) posterity.

By now you must be thinking, using some nice words, that this guy should really learn how to work with docker build arguments and stop wasting my time, but there is no denying it always ends up on memorizing all the arguments, which never happens.

Dockerfile

First step: meet kubectl

What kubectl is or does is out of scope for this post. We're only using it out as an example, because it was the first thing that popped into my mind.
Let's build a small container for kubectl:

FROM alpine:3.12

ADD https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/linux/amd64/kubectl /usr/local/bin/kubectl

RUN chmod +x /usr/local/bin/kubectl

ENTRYPOINT ["kubectl"]

As you can see, in just a small dockerfile, 2 hardcoded versions just jump into eyesight:

  • the alpine version itself
  • the kubectl version

Second step: some adjustments

Luckily Dockerfile syntax (evolving or not through the years) allows us to do some nice modifications:

ARG ALP_VER=3.12
FROM alpine:$ALP_VER

ARG KCTL_VER=1.18.0

ADD https://storage.googleapis.com/kubernetes-release/release/v${KCTL_VER}/bin/linux/amd64/kubectl /usr/local/bin/kubectl

RUN chmod +x /usr/local/bin/kubectl

ENTRYPOINT ["kubectl"]

So now, not only I can modify those two versions as I please, as I can build the image without passing any argument (which will build it with the default versions).

Of course I could just go and issue a docker build command that simply works with that Dockerfile and shows how I can manipulate those arguments
docker build --build-arg ALP_VER=3.11 --build-arg KCTL_VER=1.18.0 -t my_kubectl:1.18.0 ..

But that just wasn't enough for me. It's not that hard, but then I'd have to remember the argument names for several dockerfiles.

The Makefile

I decided I'd only settle for a simpler syntax.
Not only something that didn't make me type those long commands but at the same time, something a little nicer than a simple (and ugly) bash script.

Now I can just build using whatever versions I want:

  • default make build
  • another alpine version make build alpver=3.11
  • another kubectl version make build kctlver=1.17.0
  • both modified versions make build alpver=3.11 kctlver=1.17.0

I can build and push into the configured registry

  • default make
  • another alpine version make alpver=3.11
  • ... and so on ...

Or I can easily check ( without any file opening ) which things I can change on that image

  • make help

Surely there are other things that got hardcoded somewhere, like the repository name, but this is only the beginning.

Of course this isn't THE WAY nor THE ONLY WAY. I'm not that naive. I'm sure many other options are available to do it and I'd like to know about them in the comment area.

Top comments (1)

Collapse
 
libialany profile image
LibiaLany

KUBECTL_VERSION where is?