Dockerfmt: A Dockerfile Formatter(github.com) |
Dockerfmt: A Dockerfile Formatter(github.com) |
Regarding this part, you can always just run a base image and add the app yourself. I'm on mobile so can't test, but should be along these lines:
docker run --rm --name dockerfmt \
-v /path/to/Dockerfile:/tmp/Dockerfile \
golang:1.24-alpine sh -c \
"apk add git && go run github.com/reteps/dockerfmt@latest /tmp/Dockerfile"
> against an existing fileFor this part yes, you'd still need one, but it can be any of your own.
so you can still have no dockerfile and the irony is not ruined
Who formats the formatter configs?
Other formatters of course since the configs are often yaml, toml, ini or json.
I am firmly in the camp of
RUN set -e ;\
export DEBIAN_FRONTEND=noninteractive ;\
etc etc
so I guess this tool isn't for meI also have a hard time reasoning about && with anything other than the most braindead sequence of commands because: $(thing && if other_thing; then inner_thing1 && thing2; fi && ohgawd)
And I just realized while typing that out that if its parser doesn't support ; then I guess one needs to
RUN if conditional_thing \
then good_luck && \
fi && \
echo "whew"But then example show that it does support `&&`? Why the difference? I pretty much always write
RUN foo && \
bar && \
:
but it seems syntactically identical to the also valid RUN set -e && \
foo ; \
bar ; \
: FROM foo
...
FROM bar
...
It's easy to see at glance what's going on.I personally don’t find this particularly helpful but can see it helping some folks. You write enough dockerfiles, the formatting becomes irrelevant.
What pisses me off though is _inconsistency_. One code base uses "formatting practices 1b", then another code base uses "formatting practices 2x". Then the worst offender: a service owners that can’t make up their mind and each developer makes up their own "best practices".
[1] https://stackoverflow.com/questions/272210/sql-statement-ind...
I wish projects would adopt/create their own formatters like go and rust.
The amount of time I have wasted discussing "best practices" with "senior" engineers is way too damn high.
In code bases such as go or rust, the discussion ends with the "the built in formatter and preferences is preferred"
Then we’ll need a formatter formatter.
Software is like onions said Shrek to Donkey.
For anyone looking to try dockerfmt, I just added a plugin to Qlty CLI, which is available in v0.508.0. The plugin took about ten minutes to add: https://github.com/qltysh/qlty/blob/main/qlty-plugins/plugin...
Full disclosure: I'm the founder of Qlty, which produces a universal code linter and formatter, Qlty CLI (https://github.com/qltysh/qlty). It is completely free and published under a Fair Source license.
Clean diffs matter irrespective of the author being a person or a program. But sure, I guess with the current hype a certain ratio of comments need to plug reminders that we are currently living in a code generation wasteland.
I find it more readable and portable.
[1] https://www.docker.com/blog/introduction-to-heredocs-in-dock...
# syntax=docker/dockerfile:1.3-labs
FROM alpine
RUN <<EOF
echo "This is a heredoc example"
echo "It allows multi-line commands"
EOF
Non-meta: Do you happen to know how portable that is across old docker, podman/buildah, kaniko, etc.? I'd like to adopt it but I don't want it to bite me when I'm not running a recent version of literal docker.> Try to make the Dockerfile easy to understand/read. It may be tempting, for the sake of brevity, to put complicated initialization details into a standalone script and merely add a RUN command in the Dockerfile. However, this causes the resulting Dockerfile to be overly opaque, and such Dockerfiles are unlikely to pass review. Instead, it is recommended to put all the commands for initialization into the Dockerfile as appropriate RUN or ENV command combinations. To find good examples, look at the current official images.
if [ foo ] ; then
bar
fi
to if [ foo ]
then
bar
fi
And also format your example to foo
bar
In this type of situation, it becomes a little trickier to disambiguate when I need to add semicolons and a backslash, and when I need to add only backslashes. If you use `&&` -- you have disambiguated the two cases so I can format it.https://docs.docker.com/build/buildkit/dockerfile-release-no...
If any organization adopted the spec I would hope they would at least make it adopt a standard file extension like .oci so it would at least be more easily recognizable by IDEs, I have never liked having to put the use case as the extension like Dockerfile.dev
But I do like that docker and buildkit have been able to freely evolve the spec with things like advanced caching directives that work great in buildx
Dockerfiles is the language for specifying a set of instructions for building container images.
# syntax=docker/dockerfile:1
I suspect that the GP was really asking "why not use a different tool", like buildah <https://buildah.io>, buildpacks <https://buildpacks.io>, nix <https://nix.dev/tutorials/nixos/building-and-running-docker-...>,
kaniko <https://github.com/GoogleContainerTools/kaniko>, ko <https://github.com/ko-build/ko>, bazel <https://github.com/bazel-contrib/rules_oci>, apko <https://github.com/chainguard-dev/apko>, or other tools.Each of those has tradeoffs compared to Dockerfiles (I have no need for bazel, but if I did, then adding `rules_oci` might be a win-win, rather than using a Dockerfile). If I used Nix, then the Nix dockerTools would be a huge win (I don't use Nix). If I were shipping Go programs, `ko` would likely be a good baseline.
$ bash -ec 'echo hello && ls -la /tmp/ | grep systemd && false && echo testing'
hello
drwx------. 3 root root 60 Mar 29 18:33 systemd-private-bluetooth.service-yuSMVM
drwx------. 3 root root 60 Mar 29 18:33 systemd-private-upower.service-YhHHP2
versus $ bash -euxc 'echo hello; ls -la /tmp/ | grep systemd; false; echo testing'
+ echo hello
hello
+ ls -la /tmp/
+ grep systemd
drwx------. 3 root root 60 Mar 29 18:33 systemd-private-bluetooth.service-yuSMVM
drwx------. 3 root root 60 Mar 29 18:33 systemd-private-upower.service-YhHHP2
+ false
Docker also supports the `SHELL` syntax now, which is even better, because you can set it once at the top of the Dockerfile without having to do the whole `set -eux` on every line.You lose automatic layer caching, but in exchange you can use the same tools (RUN, ADD, etc) within a much more powerful shell environment.
I wrote a Buildah wrapper that uses a shell script harness to polyfill the familiar Dockerfile syntax while adding several extra goodies - mainly the ability to bake runtime arguments (mounts, ports...) into the image. Very handy!
That said, in the end I'd still rather build containers with something other than an imperative sequence of commands, so my heart is going to be forever with nix2container and bazel's rules_oci.