Here’s a little known fact: “docker build” can trivially be extended to build buildpacks or CNB. Now that the buildkit refactoring is complete, Dockerfiles are just the default frontend. There’s already a buildpack frontend in the community repo, and it works great. Writing your own frontend is real straightforward.<p>Honestly after years of stagnation, the most exciting work on container building is now coming out of Docker. Buildkit is amazing, a real hidden gem.<p>See <a href="https://github.com/moby/buildkit" rel="nofollow">https://github.com/moby/buildkit</a>
I've been very close to creating something like this internally. It is easy to write a Dockerfile that produces a compact and optimal container. But it's the same lines of code over and over again. Anything we have that's a static site looks like:<p><pre><code> FROM node:10 AS build
WORKDIR /foo
COPY . .
RUN npm i
RUN npx webpack
FROM nginx:whatever
COPY nginx.conf /etc/nginx/config.d/
COPY --from=build /foo/dist /srv
...
</code></pre>
It's fine when you have one. Annoying when you have a couple. This isn't code that needs to be checked into the repository and updated. It needs to just work.<p>The other thing I'd like to see is the ability to output multiple containers from one Dockerfile. There is so much wasted work where I have webpack stuff and a go application that run in separate containers but are built together. There is one Dockerfile like the above to build the static part. There is another to build the go binary and copy it to an almost-pristine alpine container (including dumb-init, cacerts, tzdata, and grpc_health_probe). I don't understand why I have to have two Docker files to do that.
I'm a novice docker user, but I found Dockerfiles to be probably the most direct, graspable, important part of docker.<p>It's one readable text file used to recreate an entire environment. It's sort of a picture worth a thousand command lines.<p>That said, I wish there was a way to get rid of all the && stuff, which is used to avoild writing a layer of the filesytem.<p>Why not have something like:<p><pre><code> RUN foo
RUN bar
RUN bletch
LAYER</code></pre>
You are setting up an entire operating system to install a single Microservice and just now noticed that you have redundancies?<p>You could have the same issue by simply trying to rpmbuild your app. No really, you are just doing packaging. If you want more comfort, look into how redhat or Debian maintain their packages. They have similar problems and most likely they have mature solutions.
I've always felt that buildpacks in Heroku / Cloud Foundry are the way to go as they offer a higher level of abstraction than Docker files. The resulting containers are often production ready with good default settings. In docker you are re-inventing the wheel more often than not.
I wish this had gone into some more technical detail about what "CNB" does that is actually better. Most of the article was just rehashing some problems with Dockerfiles, but the conclusion is just "CNB fixes it!" The one specific improvement they mention is being able to "rebase" an image without rebuilding the whole thing, which certainly sounds interesting, but is not explained. How does it work? What else is CNB other than a wrapper around `docker build`?
I like they way they highlight that combining Ruby and nodejs makes for a complicated Dockerfile, while their example after only includes Ruby and not nodejs. And do they propose a buildpack called ruby-nodejs, because in many cases you don't need nodejs in your Ruby app. OMG now buildpack's are a leaky abstraction!
I love the fact Heroku have open-sourced their buildpacks. Dokku takes great use of these and provides a very similar platform to themselves that you can host yourself (DigitalOcean even provide a base-image that will pre-configure Dokku for you). Great for personal websites and the like.<p>If you want to scale in a pinch then it's a case of making some tiny tweaks and pushing to Heroku instead.
It's nice that they've built a tool that understands specific application contexts and can do the right things to build an efficient image. But imo that does not make the dockerfile a leaky abstraction.
I just saw a submission on the "demise" of Cloud Foundry (a Heroku-like PaaS) that's relevant to this discussion: <a href="https://medium.com/@krishnan/lessons-from-the-demise-of-cloudfoundry-ed4f77a08a73" rel="nofollow">https://medium.com/@krishnan/lessons-from-the-demise-of-clou...</a><p><i>Opinionated Platforms Are Risky: The CloudFoundry platform was more opinionated than some competing platforms in the market. In fact, the biggest debate between CloudFoundry and its direct competitors was about whether customers need opinionated platforms or not. CloudFoundry only supported 12 factor applications whereas platforms built on top of Kubernetes could support both stateful and stateless (12 factor) applications.</i><p>If you're building a stateless 12-factor app <i>and</i> there's a buildpack that does what you want, buildpacks are clearly better than lower-level Dockerfiles. But there's no buildpack for something like a database and there probably never will be, so the flexibility of directly building containers needs to exist.
It took me a while to get the pun, it doesn't show up in the article anywhere from what I could fine and I don't actually see how you're defending against anything here so I wonder - Did you just have this pun sitting around and were itching to use it somewhere, anywhere?
So instead of a Dockerfile we now need a builder.toml file. In addition you need a detect and build script:
<a href="https://buildpacks.io/docs/create-buildpack/building-blocks-cnb/" rel="nofollow">https://buildpacks.io/docs/create-buildpack/building-blocks-...</a>
Is this really a simplification?
It's not a case of buildpacks vs dockerfiles. They both solve different problems with different solutions.<p>Buildpacks fit nicely into the heroku way of doing things. But at any medium to large sized engineering organization, there's no way they could satisfy the requirements for even a simple majority of services that using a Dockerfile provides.
This seems written from an outdated perspective of Dockerfiles -- multi-stage builds landed in Docker 17.05 which are almost a year old and address most of the concerns in the article...
”Mixing operational concerns with application concerns like this results in a poor tool for developers who just want to write code and ship it as painlessly as possible.”<p>Yeah, throw that code over to the ops team. Let them figure stuff out themselves.
> creating Cloud Native Buildpacks (CNB), a standard for turning source code into Docker images without the need for Dockerfile<p>This is a solution in search of a problem. Please stop.