Building images with DockerFile¶
The functionality of
DockerFile is centered around creating Dockerfile’s for
Docker images. Although it is not particularly hard to write them directly, doing so requires you to remember what to
configure where. In some instances (e.g. commands, ports etc.) this may be done at run-time using a configuration
utility. However, if there are more dynamic elements, e.g. paths and version numbers, you can end up having to change
them in multiple places.
This implementation aims to make Dockerfiles easy to generate by Python code. Approaches in detail may vary, i.e. some may prefer to insert commands one-by-one, whereas others would rather use a format string to insert variables. It is possible to combine such methods.
A new Dockerfile can be created with the following commands:
from dockermap.api import DockerFile df = DockerFile('ubuntu', maintainer='ME, email@example.com', initial='RUN apt-get update\nRUN apt-get -y upgrade')
The first argument is the base image, as every new Docker image should have one.
maintainer argument is optional, and is written with a
MAINTAINER prefix. Afterwards, the contents of
initial (also optional) are written to the Dockerfile.
Internally, instantiation creates a string buffer and some configuration variables. All action commands where the order
is relevant, e.g.
RUN, are written to this buffer immediately, whereas configuration commands such as
delayed until a finalization step.
Except for being embedded in a context tarball, the Dockerfile is never actually stored by itself. If you wish to do so,
you can use
The following actions are performed on the string buffer immediately:
Passing in a base image, a maintainer, or
initial contents on instantiation. Plain Dockerfile commands can be used
initial, as found in the Dockerfile reference. The base image is prefixed with
FROM, whereas the
maintainer is inserted with
MAINTAINER. None of the
initial commands are processed any further, so they should
be formatted properly and contain line breaks.
In order to insert
RUN commands for execution during the build process, use
run_all(). They are convenience methods for
prefix_all('RUN', 'command 1', 'command 2', ...).
Files can be added using
add_archive(). The former adds a single file or directory, whereas the
latter adds the contents of a tar archive. By default, all files and directories will be inserted at the root of
the container’s filesystem, maintaining their original structure of subdirectories where applicable.
Inserting a file or archive also adds an entry to a list which is used for building the context tarball. The latter carries all file-based information that is later sent to the Docker Remote API, including the finalized Dockerfile. Files and directories will simply be added to the context archive, whereas archives’ contents are extracted and recompressed without storing additional temporary files.
Target directories inside the image can be specified for
further arguments. For archives, this is currently not supported, so existing tarballs should be structured in a
way suitable for the image.
For example, a file may also be added with the following arguments:
dockerfile.add_file('~/my_file', '/new_dir/my_file', '/another_file', expanduser=True, remove_final=True)
- The first argument is the current actual place in the file system from where Docker-Map is run. If this includes
variables, such as the current user home
expandusershould be set to
Truefor resolving it to an absolute path name. Similarly, environment variables can be used when passing
- The second argument defines the target path in the final image. By default, the file would have ended up in
- The third argument is also optional, and specifies the path inside the context archive. By default it is identical to the image’s destination path, and can be used in case conflicts arise from adding multiple files or directories with identical names.
remove_finalinserts a removal command (e.g.
RUN rm -Rf /new_dir/my_file) at the end of the Dockerfile, but before configuration commands. You may want to set this to clean up the file system of the final image from files and directories that were only needed during the build process. Please note that due to the file system layering that Docker uses, this will not actually make the image smaller.
Miscellaneous Docker commands¶
Any Dockerfile command, or a series thereof, can be inserted with
These insert strings prefixed with a Dockerfile command. Following convenience methods should be preferred where
The following are set as properties to a Dockerfile. They are appended as soon as
finalize() is called. Afterwards no more changes are allowed to the
object. Typically it is not necessary to call
volumes defines the list of volumes that a container in its
default configuration will share. The list will be inserted prefixed with a
VOLUME command, before any other of the
following finalizing commands.
Entry point and default command¶
command do the same as inserting
CMD in the
Dockerfile. They can be set either as a list/tuple of strings, or a single string separated with spaces. Depending on
command_shell, they are either written as a shell command in the
Dockerfile (i.e. with spaces) or as an exec command (i.e. as a list).
command_user property sets the default user for
ENTRYPOINT. It is therefore inserted directly before them.
In contrast to inserting the
USER command directly, this does not change the user for other
commands in the Dockerfile. You can still use
prefix('USER', 'username') if you need to change users during the
command_workdir sets the working directory for
CMD. It does however not change directories immediately, i.e. does not affect
Building the Docker image¶
For starting the build process, pass the
DockerFile to the Docker Remote API with
the enhanced client method
from dockermap.api import DockerClientWrapper, DockerFile client = DockerClientWrapper('unix://var/run/docker.sock') dockerfile = DockerFile('ubuntu', maintainer='ME, firstname.lastname@example.org') dockerfile.add_file(...) dockerfile.run_all(...) ... client.build_from_file(dockerfile, 'new_image')