yjftsjthsd-h 10 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 ; \
      :

3
mcstafford 10 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 10 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 9 days ago

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

solatic 10 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 9 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 9 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 9 days ago

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

spicypete 10 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 10 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 10 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 10 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;)