Search code examples
dockershheredoc

Run program after heredoc in same RUN statement in Dockerfile


I would like to create a file using heredoc and then run a command after in the same RUN statement in a Dockerfile.

To illustrate, take this Dockerfile

FROM alpine
RUN export FOO=bar && \
    cat <<EOF > testfile
Hello, World!
EOF \
    && echo $FOO

When I try to build that, it fails with ERROR: failed to solve: unterminated heredoc.

It seems that the EOF has to be on a line by itself. But if I do that, the RUN statement ends and I have to put the next command on a new RUN statement.

I'd like to have some commands following the heredoc on the same RUN statement to minimize layers and to have the environment variable available.

Is that possible?


Solution

  • You can nest heredocs inside heredocs. For example:

    FROM alpine
    RUN <<CMD_EOF
    # NB. `set -e` is very important! It stops the run statement if one of the commands fails
    set -ex 
    export FOO=bar
    cat <<FILE_EOF >test_file
    Hello, World!
    FILE_EOF
    echo $FOO
    CMD_EOF
    RUN cat test_file
    

    This takes advantage of the initial use case for heredocs in docker -- to run a sequence of commands in one RUN statement without having to link them using && and \. The first heredoc is CMD_EOF that contains all the commands you want to run. The second, FILE_EOF, is the one that contains the contents of the file you want to create.