Discover more from Matt Rickard
Templating Magic Isn't Free
Dockerfiles are understandably tricky to write for the average developer. There are multiple kinds of instructions, and the effects happen within a containerized environment. A few bad instructions can increase build times or even introduce inconsistencies (e.g., update packages after building). In addition, cache issues always are hard to debug.
Many product managers reach for a seemingly simple solution — developers shouldn’t have to write Dockerfiles. We can quickly analyze the code and develop a decent template automatically. Buildpacks promise reusable templates for most languages or frameworks.
If you’re on the happy path, your development velocity is extreme. Only focus on your code. But template magic isn’t free. You are only deferring work. In small doses, this is OK. But as soon as you deviate from the happy path, you are left with all of the technical debt from the template. Templates like create-react-app let you “eject” the configuration into your project. Debugging becomes painfully slow and confusing. Extending the template takes up more cycles than writing your application code. Sometimes this might even be too much to move forward with.
Templating doesn’t work. Instead, there are two alternatives
Constrain the problem (create a framework). Templates try to solve the same problem space as the tools they aggregate. Frameworks focus on a narrower set of use cases. They add constraints on what you can and can’t do. This is why NextJS succeeds where create-react-app didn’t. There’s still magic, but there is no silver bullet promised.
Change the underlying API (swap the tool or build on it). Instead of autogenerating Dockerfiles for developers, why not change the API or build on it? That might mean an alternative Dockerfile format that’s more developer friendly or suited to the domain. Or It might mean providing a higher-level interface to developers. For example, instead of letting them write arbitrary Dockerfile commands, they might specify the packages that should be installed via a language-specific package manager.