Using Dockerfiles
What is a Dockerfile?
See Dockerfile reference in the Docker docs.
An example
Copied from Best practices for writing Dockerfiles
FROM ubuntu:18.04
COPY . /app
RUN make /app
CMD python /app/app.py
Each instruction creates one layer:
FROM
creates a layer from the ubuntu:18.04 Docker image.COPY
adds files from your Docker client’s current directory.RUN
builds your application with make.CMD
specifies what command to run within the container.
General pattern
Here is an outline of a typical Dockerfile
.
FROM ...
RUN ...
RUN ...
RUN ...
WORKDIR ...
COPY ... ...
RUN ...
ENTRYPOINT ...
CMD ...
What do the pieces do?
FROM
The FROM
line specifies the base image, usually Linux flavor (e.g. ubuntu
) or a specialized container such as for Python or NodeJS.
If the target image does not exist yet, Docker will download it. On later build or run commands, that image will be reused from the cache.
If you want to download an image independently of using it in a FROM
line, you can run:
$ docker pull IMAGE
RUN
There are usually some RUN
commands when building the image.
- This is usually a command to update the APT package listing. This is usually required or the next step will fail.
RUN apt-get update
- Then there is a step to install packages. It is useful to add the
-q
quiet flag for cleaner output and the-y
yes flag to install without asking the user to confirm.RUN apt-get update
- The
RUN
command can also be used for other commands such as changing permissions, moving files, or downloading and unzipping a file from a URL.
WORKDIR
Set the working directory to a custom value.
This defaults to ~
- that would be /root
.
COPY
There is sometimes a COPY
commnd to copy a file or folder into the container.
Source
The source could be a file.
COPY foo.txt /root
Or the contents of a directory. Note - the contents of the directory are copied, not the directory itself.
# Similar to this in Bash: cp bar/* /root
COPY bar /root
Or a directory.
COPY bar /root/bar
Or your entire project.
COPY . /root
Destination
This is often copied to /
or /app
but ~
can work as well. Note that the user will be root
so sudo
is not needed and the path to ~
will be /root
. Also my linter recommends using an absolute rather than ~
.
I’d recommend against copying to /
since there are directories there relating to the system (similar to a system not insider a container).
CMD / ENTRYPOINT
Finally there is usually CMD
or ENTRYPOINT
at the end. This will only be run when the container starts - not during the build image step.
CMD
sets default command and/or parameters, such as starting a server or entering the Python or Bash shell. The default command can be ignored if overwritten when running the container.CMD echo "Hello world"
CMD ["/bin/bash"]
ENTRYPOINT
configures a container that will run as an executable. The entry point will always run even if the command is overwritten.ENTRYPOINT echo "Hello world"
ENTRYPOINT ["/bin/bash"]
See more info in this post.