Reputation: 4721
I would like to launch this vagrant command cat(run perfectly!) to provisionning my container with a Dockerfile :
# Configure Virtualenvwrapper.
RUN cat <<EOF >> /home/docker/.bashrc
# Virtualenvwrapper configuration.
export WORKON_HOME=\$HOME/.virtualenvs
export PROJECT_HOME=\$HOME/Devel
source /usr/local/bin/virtualenvwrapper.sh
EOF
But I have this error return when I launch my building image docker :
---> 40f9ed8e187d
Removing intermediate container 85f6c8536520
Step 69 : RUN cat <<EOF >> /home/docker/.bashrc
---> Running in dcbb3d441f79
---> 78acd9c2e5d5
Removing intermediate container dcbb3d441f79
Step 70 : EXPORT
Unknown instruction: EXPORT
What is the trick for run a cat command unix into image with Dockerfile ?
Upvotes: 30
Views: 81973
Reputation: 7812
This is an example straight from Docker documentation:
# syntax=docker/dockerfile:1
FROM alpine
ARG FOO=bar
COPY <<-EOT /app/foo
hello ${FOO}
EOT
https://docs.docker.com/engine/reference/builder/#example-creating-inline-files
Upvotes: 3
Reputation: 418
Update [08/03/2022]: As of dockerfile/dockerfile:1.4.0
, the Here-Document support has been promoted from labs channel to stable. #2589.
You need to use Docker Buildkit by setting DOCKER_BUILDKIT=1
in your environment, set the syntax parser directive to use dockerfile/dockerfile:1.4.0
, and swap the position of the here delimeter with cat
. The rest is used like normal.
Dockerfile Example:
# syntax = docker/dockerfile:1.4.0
...
RUN <<EOF cat >> /home/docker/.bashrc
# Virtualenvwrapper configuration.
export WORKON_HOME=\$HOME/.virtualenvs
export PROJECT_HOME=\$HOME/Devel
source /usr/local/bin/virtualenvwrapper.sh
EOF
Prior to dockerfile/dockerfile:1.4.0
, Here-Document syntax was supported in the labs channel dockerfile/dockerfile:1.3.0-labs
release.
Simply replace version used in the syntax
parser directive from the above example.
Prior to Docker BuildKit labs channel dockerfile/dockerfile:1.3.0-labs
release, instead of using cat
, try using echo
instead!
Turn this shell cat
example...
#!/usr/bin/env sh
cat <<EOF > /tmp/example.txt
line 1
line 2
line 3
EOF
... into this Dockerfile echo
example!
RUN echo -e '\
line 1\n\
line 2\n\
line 3\
' > /tmp/example.txt
Note the pair of single quotes ('
) in the echo
example.
Also note the -e
flag for echo
to support the escaped newlines (\n
).
Caution: Unfortunately, the -e
flag may or may not be required depending on the version of echo
your image has installed. For example, the npm:16
image's echo
does not require -e
and actually will print the -e
along with the single-quoted lines. On the other hand, the ubuntu:20.04
image's echo
does require -e
.
The same example could be written on one line as:
RUN echo -e 'line 1\nline 2\nline 3' >> /tmp/example.txt
, but I find the above example more readable.
To answer the OP's question, use this:
# Configure Virtualenvwrapper.
RUN echo -e '\
# Virtualenvwrapper configuration.\n\
export WORKON_HOME=\$HOME/.virtualenvs\n\
export PROJECT_HOME=\$HOME/Devel\n\
source /usr/local/bin/virtualenvwrapper.sh\
' >> /home/docker/.bashrc
Caution: The escape character can be redefined by the escape
directive. If your Dockerfile has a different escape character set, you'll need to modify the examples accordingly.
Upvotes: 28
Reputation: 189477
If you want to avoid here-document syntax for some reason, printf
is hugely more ergonomical than echo $'...'
as well as portable to POSIX sh
.
RUN printf '%s\n' > /home/docker/.profile \
'# Virtualenvwrapper configuration.' \
'export WORKON_HOME=$HOME/.virtualenvs' \
'export PROJECT_HOME=$HOME/Devel' \
'source /usr/local/bin/virtualenvwrapper.sh'
The single quotes prevent shell interpolation of variables; if you want to expand a variable, use double quotes (though then you'll need to backslash-escape any literal dollar sign, backtick, or backslash).
Upvotes: 0
Reputation: 137
You can also use below command in place of here document << inside a Dockerfile
RUN echo $'[kubernetes] \n\
name=Kubernetes \n\
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 \n\
enabled=1 \n\
gpgcheck=1 \n\
repo_gpgcheck=1 \n\
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg \n '\
> /etc/yum.repos.d/kubernetes.repo
Upvotes: 3
Reputation: 1668
Based on this comment to an issue posted on Github, this works:
RUN echo 'All of your\n\
multiline that you ever wanted\n\
into a dockerfile\n'\
>> /etc/example.conf
Upvotes: 33
Reputation: 2417
You can write it this way:
RUN echo "# Virtualenvwrapper configuration." >> /home/docker/.bashrc && \
echo "export WORKON_HOME=\$HOME/.virtualenvs" >> /home/docker/.bashrc && \
echo "export PROJECT_HOME=\$HOME/Devel" >> /home/docker/.bashrc && \
echo "source /usr/local/bin/virtualenvwrapper.sh" >> /home/docker/.bashrc
Upvotes: 5
Reputation: 13095
Dockerfiles are not batch files. Every line/command is isolated and committed.
Just put the contents into a file and ADD/COPY it. If you need to customize it, SED it. Or if you really, really, really want to CAT into a file -- put it in a real batch file, then ADD/COPY it, then RUN it.
Also, less lines = less layers. 70 Steps? Yowzers.
Upvotes: 6