github.com
135
62
jensenbox 9 days ago

I had a chuckle when I looked at the source code and could not find a Dockerfile in there. I want to kick the tires on it and the easiest way would be to run it as a Docker container against an existing file and alas, I cannot.

PhilippGille 9 days ago

> the easiest way would be to run it as a Docker container

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 file

For this part yes, you'd still need one, but it can be any of your own.

spicypete 9 days ago

Hi there — I’ll try to distribute a docker release of the binary tomorrow!

ithkuil 9 days ago

I suggest you build it with https://github.com/ko-build/ko

so you can still have no dockerfile and the irony is not ruined

IshKebab 9 days ago

I think they were asking for a sample Dockerfile in the repo to test it on.

spicypete 8 days ago

Then they can use one of the 14 in the `tests` directory :) https://github.com/reteps/dockerfmt/tree/main/tests

klysm 9 days ago

The project should certainly also be formatting its own docker file via a docker invocation

thedougd 9 days ago

And built in a multistage Dockerfile.

revskill 9 days ago

The author doesn't know how to use AI.

krick 8 days ago

I usually share the sentiment, but, come on, it's packaged as a single binary file...

mdaniel 8 days ago

I don't want to vouch for the flagged and dead comment https://news.ycombinator.com/item?id=43630653 because I suspect it was killed for its tone but wow it is really illustrative of the QA that didn't go into this product

spicypete 8 days ago

What I can do for you is fix the bugs promptly! I resolved the bugs in the `0.2.7` release. I haven't graduated college yet and don't have a full time job, so my QA skills are still improving.

adastra22 8 days ago

Everyone starts somewhere. Good for you for putting it out there!

grandempire 8 days ago

You aren’t a real software engineer if your project doesn’t have 50 dot files in the root for your formatters, package mangers, linters, and ci.

Who formats the formatter configs?

zufallsheld 8 days ago

> Who formats the formatter configs?

Other formatters of course since the configs are often yaml, toml, ini or json.

mdaniel 9 days ago

waaaat? https://github.com/reteps/dockerfmt#:~:text=The%20RUN%20pars...

I am firmly in the camp of

  RUN set -e ;\
      export DEBIAN_FRONTEND=noninteractive ;\
      etc etc
so I guess this tool isn't for me

rgovostes 9 days ago

As far as I can tell from https://github.com/moby/moby/issues/4032, as of Debian 12 "bookworm" and Ubuntu 23.04 "Lunar", explicitly setting DEBIAN_FRONTEND is no longer necessary.

spicypete 9 days ago

Is there any reason you prefer `set -e` over `&&`? I'm curious if this is a readability thing.

figmert 9 days ago

I'm firmly in that camp but I also always add `set -eux`, which makes it so much better at debugging as that gives you individual commands it runs before the output of them.

figmert 8 days ago

To be clear, the difference is something along this line:

    $ 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.

mdaniel 8 days ago

Readability is putting it mildly; do you write your shell scripts using that && style? No? Why not, is it for readability?

I 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"

spicypete 8 days ago

This is a valid point -- I replied to why this is the way it is here: https://news.ycombinator.com/item?id=43629049. I understand it's not ideal for many, and I am open to PRs!

yjftsjthsd-h 9 days ago

> The RUN parser currently doesn't support grouping or semicolons in commands

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 ; \
      :

mcstafford 9 days ago

I prefer heredoc[1] syntax.

I find it more readable and portable.

[1] https://www.docker.com/blog/introduction-to-heredocs-in-dock...

yjftsjthsd-h 9 days ago

Meta: In HN, prefix a line with 2 spaces to get code formatting, ex.

  # 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.

vbezhenar 8 days ago

It is new feature and not portable to old versions. But modern podman supports it. No idea about kaniko.

solatic 9 days ago

Or, you can write an actual shell script file (i.e. with a .sh extension) to be stored in your repository, ADD it in a throwaway context (i.e. multi-stage builds), then RUN --mount=type=bind to put it into a temporary directory in the build container so that you can execute it. This way, the script doesn't pollute the container, and you have proper separation of concerns, including the ability to use library functions, running shell linters directly, or using higher-level languages like Python if you really need it for some reason

xenophonf 8 days ago

That's bad practice because it hides build steps from `docker inspect`. Per https://github.com/docker-library/official-images#clarity:

> 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.

solatic 8 days ago

That's advice specifically for official images, and it dates back before multi-stage builds. Most people are not building official images. Most people benefit from clear encapsulation and separation of concerns. The Dockerfile sets up the environment to run the provisioning script, and a provisioning script does the actual provisioning. Official images are different because usually the provisioning script is hidden in an OS package installed with e.g. apk add (or are we going to pretend that OS packages are bad practice for the same reason?).

yjftsjthsd-h 8 days ago

Don't multi-stage builds already break `docker inspect`?

spicypete 9 days ago

I use `mvdan/sh` [1] under the hood for processing the commands. So it will reformat

  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.

[1] https://github.com/mvdan/sh

yjftsjthsd-h 9 days ago

Between that and the difficulty with comments, it feels like maybe not an ideal tool for the job? Although, I can't throw stones; I'd do almost anything to avoid having to write my own parser. (And not meant as an attack regardless, just trying to constructively question this particular design point)

spicypete 9 days ago

I am certainly not in the business of writing my own shell parser ;) Though this is a fair point -- I think I could get a more rich level of control over the output by hooking into their parser, albeit with a higher level of complexity.

yjftsjthsd-h 9 days ago

/shrug Something to think about. Usually I'd say not to worry about it, but this particular point seems to be actively causing actual problems, so it might be worth looking at. Alternatively, if the pain points you've discovered really are all there are to find, then it might well be less trouble to just patch over them specifically and not worry about it. Ugly solutions that work well and don't take extra work are good solutions in my book;)

urxvtcd 9 days ago

I'd love to indent the body of each stage in multi-stage dockerfiles, like:

    FROM foo
        ...

    FROM bar
        ...
It's easy to see at glance what's going on.

xyst 8 days ago

This reminds me of SQL indentation “best practices” discussion [1]

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...

xyst 8 days ago

It’s wild that this has to be a third party offering.

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"

nikeee 9 days ago

How does it handle multi-stage Dockerfiles? I always indent the steps following FROM to make the stages more obvious. I don't get why that isn't a norm because not doing it seems like not indenting function bodies in other languages.

QuarterDuplex 9 days ago

OK but is there any way to layer docker files? I'm not talking about compose, I mean like combining layers from different dockers in a nice way?

brigandish 9 days ago

That sounds like multi-stage builds https://docs.docker.com/build/building/multi-stage/

QuarterDuplex 9 days ago

or more like combining steps without explicitly having to combine layers?

travisgriggs 8 days ago

I hope there’s a config file for dockerfmt. Over time, it will get more and more options. It will approach Turing completeness.

Then we’ll need a formatter formatter.

Software is like onions said Shrek to Donkey.

righthand 9 days ago

I just use a yaml LSP which will probably try to lookup the schema.org Containerfile format for this. I first noticed this recently when working on a Github Actions yaml file. Pretty nifty.

whalesalad 9 days ago

But a dockerfile is not yaml. do you mean for docker compose?

righthand 9 days ago

You’re right. I’m sure there is a containerfile lsp however.

https://github.com/sublimelsp/LSP-dockerfile

dddw 9 days ago

This wouldve come in hansy yesterday

PantaloonFlames 9 days ago

Side question. Why would people continue to build new dockerfiles as opposed to using Podman ?

dharmab 9 days ago

Dockerfile has been standardized as Containerfile: https://github.com/containers/common/blob/main/docs/Containe...

caleblloyd 9 days ago

Dockerfile seems very specific to Docker still, I don’t think they have to go through a committee to add anything to the spec

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

DazWilkin 9 days ago

Podman uses Dockerfiles too.

Dockerfiles is the language for specifying a set of instructions for building container images.

halostatue 9 days ago

It's not a very good one, but it is ubiquitous (it's also better if you remember to include the right syntax marker that enables heredocs):

    # 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.

colonial 9 days ago

Buildah is the only serious alternative in my opinion.

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!

mikepurvis 9 days ago

Buildah's ability to mount the container in an unshare environment is pretty magical for copying stuff in and out of it.

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.

yjftsjthsd-h 9 days ago

When I've used buildah and kaniko, I still handed them a Dockerfile.

jahsome 9 days ago

Why would people continue to use hackernews as opposed to reddit?

bpiroman 9 days ago

I feel dumber after using reddit

imp0cat 9 days ago

The same is usually said about watching Spongebob Squarepants, but YMMV. :)

chuckadams 8 days ago

At least with Spongebob you feel dumb and happy. Feels like the whole world is dumb and angry now.

brynary 9 days ago

It's great to see auto-formatting continuing to become universal across all languages. As LLMs write more code, full auto-formatting helps keep diffs clean.

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.

keybored 9 days ago

> As LLMs write more code, full auto-formatting helps keep diffs clean.

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.