Docker Building images
Parameters[edit | edit source]
|--pull||Ensures that the base image (|
Building an image from a Dockerfile[edit | edit source]
Once you have a Dockerfile, you can build an image from it using
docker build. The basic form of this command is:
docker build -t image-name path
If your Dockerfile isn't named
Dockerfile, you can use the
-f flag to give the name of the Dockerfile to build.
docker build -t image-name -f Dockerfile2 .
For example, to build an image named
dockerbuild-example:1.0.0 from a
Dockerfile in the current working directory:
$ ls Dockerfile Dockerfile2 $ docker build -t dockerbuild-example:1.0.0 . $ docker build -t dockerbuild-example-2:1.0.0 -f Dockerfile2 .
docker build usage documentation for more options and settings.
A common mistake is creating a Dockerfile in the user home directory (
~). This is a bad idea because during
docker build -t mytag . this message will appear for a long time:
The cause is the docker daemon trying to copy all the user's files (both the home directory and it's subdirectories). Avoid this by always specifying a directory for the Dockerfile.
.dockerignore file to the build directory is a good practice. Its syntax is similar to
.gitignore files and will make sure only wanted files and directories are uploaded as the context of the build.
Difference between ENTRYPOINT and CMD[edit | edit source]
There are two
Dockerfile directives to specify what command to run by default in built images. If you only specify
CMD then docker will run that command using the default
ENTRYPOINT, which is
/bin/sh -c. You can override either or both the entrypoint and/or the command when you start up the built image. If you specify both, then the
ENTRYPOINT specifies the executable of your container process, and
CMD will be supplied as the parameters of that executable.
For example if your
FROM ubuntu:16.04 CMD ["/bin/date"]
Then you are using the default
ENTRYPOINT directive of
/bin/sh -c, and running
/bin/date with that default entrypoint. The command of your container process will be
/bin/sh -c /bin/date. Once you run this image then it will by default print out the current date
$ docker build -t test . $ docker run test Tue Jul 19 10:37:43 UTC 2016
You can override
CMD on the command line, in which case it will run the command you have specified.
$ docker run test /bin/hostname bf0274ec8820
If you specify an
ENTRYPOINT directive, Docker will use that executable, and the
CMD directive specifies the default parameter(s) of the command. So if your
FROM ubuntu:16.04 ENTRYPOINT ["/bin/echo"] CMD ["Hello"]
Then running it will produce
$ docker build -t test . $ docker run test Hello
You can provide different parameters if you want to, but they will all run
$ docker run test Hi Hi
If you want to override the entrypoint listed in your Dockerfile (i.e. if you wish to run a different command than
echo in this container), then you need to specify the
--entrypoint parameter on the command line:
$ docker run --entrypoint=/bin/hostname test b2c70e74df18
Generally you use the
ENTRYPOINT directive to point to your main application you want to run, and
CMD to the default parameters.
A simple Dockerfile[edit | edit source]
FROM directive specifies an image to start from. Any valid image reference may be used.
WORKDIR directive sets the current working directory inside the container, equivalent to running
cd inside the container. (Note:
RUN cd will not change the current working directory.)
RUN npm install cowsay knock-knock-jokes
RUN executes the given command inside the container.
COPY cowsay-knockknock.js ./
COPY copies the file or directory specified in the first argument from the build context (the
path passed to
docker build path) to the location in the container specified by the second argument.
CMD node cowsay-knockknock.js
There are many other instructions and options; see the Dockerfile reference for a complete list.
Pushing and Pulling an Image to Docker Hub or another Registry[edit | edit source]
Locally created images can be pushed to Docker Hub or any other docker repo host, known as a registry. Use
docker login to sign in to an existing docker hub account.
docker login Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username: cjsimon Password: Login Succeeded
A different docker registry can be used by specifying a server name. This also works for private or self-hosted registries. Further, using an external credentials store for safety is possible.
docker login quay.io
You can then tag and push images to the registry that you are logged in to. Your repository must be specified as
server/username/reponame:tag. Omitting the server currently defaults to Docker Hub. (The default registry cannot be changed to another provider, and there are no plans to implement this feature.)
docker tag mynginx quay.io/cjsimon/mynginx:latest
Different tags can be used to represent different versions, or branches, of the same image. An image with multiple different tags will display each tag in the same repo.
docker images to see a list of installed images installed on your local machine, including your newly tagged image. Then use push to upload it to the registry and pull to download the image.
docker push quay.io/cjsimon/mynginx:latest
All tags of an images can be pulled by specifying the
docker pull quay.io/cjsimon/mynginx:latest
Exposing a Port in the Dockerfile[edit | edit source]
EXPOSE <port> [<port>...]
EXPOSEinstruction informs Docker that the container listens on the specified network ports at runtime.
EXPOSEdoes not make the ports of the container accessible to the host. To do that, you must use either the
-pflag to publish a range of ports or the
-Pflag to publish all of the exposed ports. You can expose one port number and publish it externally under another number.
Example:[edit | edit source]
Inside your Dockerfile:
To access this port from the host machine, include this argument in your
docker run command:
ENTRYPOINT and CMD seen as verb and parameter[edit | edit source]
Suppose you have a Dockerfile ending with
ENTRYPOINT [ "nethogs"] CMD ["wlan0"]
if you build this image with a
docker built -t inspector .
launch the image built with such a Dockerfile with a command such as
docker run -it --net=host --rm inspector
,nethogs will monitor the interface named wlan0
Now if you want to monitor the interface eth0 (or wlan1, or ra1...), you will do something like
docker run -it --net=host --rm inspector eth0
docker run -it --net=host --rm inspector wlan1
Building using a proxy[edit | edit source]
Often when building a Docker image, the Dockerfile contains instructions that runs programs to fetch resources from the Internet (
wget for example to pull a program binary build on GitHub for example).
It is possible to instruct Docker to pass set set environment variables so that such programs perform those fetches through a proxy:
$ docker build --build-arg http_proxy=http://myproxy.example.com:3128 \ --build-arg https_proxy=http://myproxy.example.com:3128 \ --build-arg no_proxy=internal.example.com \ -t test .
build*arg are environment variables which are available at build time only.