Docker
Guide to synax for a
Dockerfile
See Dockerfile reference doc.
Overview
Dockerfile
FROM image-name ENV foo=bar ARG fizz=buzz RUN apt-get update RUN apt install -q -y foo RUN echo hello
Set working directory
This is useful to a working directory for subsequent commands in the image build or container running. Especially if you start in interactive mode and want to start at an appropriate directory.
If the directory does not exist, you must create it.
Dockerfile
RUN mkdir /root/foo WORKDIR /root/foo
I read that using absolute paths is preferred in a container over a path like ~/foo
.
Copy
Use the COPY
command directories into an image.
COPY SRC DEST
e.g.
COPY . .
COPY src .
COPY package*.json .
COPY foo /bar/
COPY foo /root/bar/
Using absolute destinations is preferred. So avoid using ~/bar
, though it can actually work to point to the root userโs home.
You can also set the working directory in the image before your copy steps, to avoid using the prefix each time.
MKDIR /root/app
WORKDIR /root/app
COPY . .
Note that this works differently to the plain cp
command - the contents of the source directory are copied, not the directory itself.
So to keep the destination as lib
, why you would use COPY lib lib
rather than COPY lib .
See also the older ADD
command which is not used as much. It allows referencing a zip file on a URL, but the preferred way in the docs is to use curl
and tar
in a RUN
command.
See Add vs Copy article.
See in the docs:
See also docker cp
as a CLI command to copy a file into a container rather than using COPY
for building the image.
Note that the source path is relative to the build context (usually the root of your repo). You cannot use any relative or absolute paths outside the context, such as paths like /
, ..
or ~/
.
If you want to copy from outside the project:
cd ..
docker build -t my-app -f src/Dockerfile .
Run commands
The Run syntax to run in the shell at image build time.
See the Command or Entry sections for changing what a container executes.
Run
RUN docs reference.
The RUN instruction will execute any commands in a new layer on top of the current image and commit the results. The resulting committed image will be used for the next step in the Dockerfile.
Two forms:
- Shell form.
RUN command
- Exec form.
RUN ["executable", "param1", "param2"]
e.g.
RUN foo bar
RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME'
Note that the exec form is parsed as a JSON array, which means that you must use double-quotes (โ
) around words not single-quotes (โ
).
RUN ["boo", "bar"]
RUN ["/bin/bash", "-c", "echo Hello"]
# You must use the subshell in exec form to evaluate variables.
RUN [ "sh", "-c", "echo $HOME" ]
Command
See CMD doc reference.
The main purpose of a CMD
is to provide defaults for an executing container.
There can only be one CMD
instruction in a Dockerfile - only last is used.
The CMD
instruction has three forms:
- Exec form - preferred.
CMD ["executable", "param1", "param2"] # (exec form, this is the preferred form)
- Shell form:
CMD command param1 param2
Arguments
ARG doc reference.
Set a build-time arg.
$ docker build --build-arg <varname>=<value>
ARG <name>[=<default value>]
Example:
FROM busybox
ARG user1
ARG buildno
# ...
Using ARG
and FROM
together, based on the docs.
ARG CODE_VERSION=latest
FROM base:${CODE_VERSION}
CMD /code/run-app
FROM extras:${CODE_VERSION}
CMD /code/run-extras
Entrypoint
An ENTRYPOINT
allows you to configure a container that will run as an executable.
- Exec form - preferred.
ENTRYPOINT ["executable", "param1", "param2"]
- Shell form.
ENTRYPOINT command param1 param2
Set default parameters for ENTRYPOINT
:
CMD ["param1", "param2"]