heredoc in Dockerfile

Writing a Dockerfile with long scripts inside can be very annoying. Instead use a heredoc.
Please no “&& \” over and over.

Please, no:

RUN dnf upgrade -y && \
    dnf install -y package123 && \
    rm -rf /var/cache/dnf/* && \
    dnf clean all

All those “&& \” over and over.. But the bigger issue for me is figuring out where something broke. When there’s an error the whole block of code is shown and no indication where the problem actually is!

Heredoc inside a Dockerfile / Containerfile to save the day:

RUN <<EOF
    set -ex
    dnf upgrade -y
    dnf install -y package123
    rm -rf /var/cache/dnf/*
    dnf clean all
EOF

Or even better, specify bash shell if the image has it, with pipefail:

SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN <<EOF bash
    set -ex
    # Do stuff
EOF

What is a heredoc?

As described by Wikipedia:
here document (here-document, here-text, heredoc, hereis, here-string or here-script) is a file literal or input stream literal: it is a section of a source code file that is treated as if it were a separate file. The term is also used for a form of multiline string literals that use similar syntax, preserving line breaks and other whitespace (including indentation) in the text.
The most common syntax for here documents, originating in Unix shells, is << followed by a delimiting identifier (often the word EOF or END), followed, starting on the next line, by the text to be quoted, and then closed by the same delimiting identifier on its own line. This syntax is because here documents are formally stream literals, and the content of the here document is often redirected to stdin (standard input) of the preceding command or current shell script/executable.
The here document syntax is analogous to the shell syntax for input redirection, which is < followed by the name of the file to be used as input.

More information about heredocs is in Docker’s announcement. Podman also supports heredocs.

Neo from The Matrix saying: "I know docker". Maybe he also knows heredoc

Conclusion

Writing long scripts in a Dockerfile / Containerfile is painful. Use heredocs instead to make life easier. Why isn’t this the default for every single example on the internet already?

This will also help if you start using bootc (Bootable Containers)!