Docker
Guide to synax for a
Dockerfile
See Dockerfile reference doc.
Overview
DockerfileFROM 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.
DockerfileRUN 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"]