Please stop writing Dockerfiles

Mostly what you're doing when you give these choices to application developers is giving them opportunities to get bitten by clowns.

Please stop writing Dockerfiles
Photo by Krisffer Aeviel Cabral / Unsplash

Hey there! This is Nat, from Simpler Machines. You're reading my newsletter about making software.

There are two parts in particular of our Kubernetes hellscape that seem like pure clowntown to me: Having application developers build their own containers and maintain their own Dockerfiles, and maintaining Dockerfiles for each individual application.

Expecting application developers to be responsible for their builds is good, so I can see we got here. But jesus the overhead! There are a lot of choices and a lot of details and they're all going to be basically the same for most applications.

What base image should we use? How do we put the image into the image repository? How do we get it back out again and onto the platform? What packages should we build into the image, and where should we get them? What command should we use to start the app? Should we put sidecar process into the jar with the application, or run them in their own container? What environment variables should we set? How should we get credentials into the application? When and how should we build the application code into the runnable artifact? And on and on and on and on.

Mostly what you're doing when you give these choices to application developers is giving them opportunities to get bitten by clowns wreck someone's day during a security incident.

"But how else am I supposed to get a docker image?" you might reasonably ask. And the answer is almost certainly buildpacks.

In fact, if you're having to build a container as part of your day job, I highly recommend getting over to the buildpack website right now and trying out the pack CLI and the buildpack for your language.

(Aside #2: A lot of application infrastructure seems like clowntown to me these days, partly because I don't know things because I've effectively been living on a desert island for the past few years while the Kubernetes revolution happened, also partly because that island was Atlantis where we built software without being bitten by clowns.)

Why use buildpacks instead of managing your own Dockerfile?

Well, basically, because if you're using a common language, you can get a docker image with something like this:

pack build sequencer --builder paketobuildpacks/builder:base

Then you also get dependency updates, the option to use a build service later if that's what you're into, and a bill o' materials. And if you build infrastructure that assumes build packs you get coverage for most of your common languages for exactly zero extra work.

In general you will get bitten by clowns substantially less.

One clown in particular by which you will not get bit: Reproducibility. It's actually pretty hard to maintain a build process that is actually for reals reproducible and hermetic and doesn't reach out to the internet. You have to test it offline, which you don't. But do you know who does? That's right, the Paketo buildpacks team. Because buildpacks have to work on submarines. I am not even slightly joking. Also banks and shit but seriously, submarines.

It is possible that your dreams of deploying apps like they do on the sea might get dashed but even for these problems there are workarounds.

First, there are only about eight languages that have commercially supported build packs. If you use, god forbid, Elixir, you might have to write your own, which will be at least somewhat harder than writing your own Dockerfile. If you're a single-language shop and you're not already supported you're not going to get nearly as much benefit out of 'em as someone running a lot of Java or a mix of languages will.

Second, you have to be able to run sidecars or daemonsets for some of the buildpacks to work correctly. In particular the Java buildpack relies on sidecar containers for telemetry daemons. If you have this problem though you could just, uh, support sidecars. If you're using Kubernetes but can't do sidecars you've either got some really interesting constraints or something has gone very very wrong.

Anyway uh if you have a reason why it totes make sense for you to be writing Dockerfiles write in because I want to hear about your horrible fascinating problems. But if you don't know why you shouldn't use buildpacks, just use buildpacks.