4.0 KiB
Building Container Images
Python projects that declare their distro dependencies using bindep can be built
into container images without any additional duplicate configuration.
The pbrx command
build-images
does this as minimally and efficiently as
possible. The aim is to produce single-process application images that
container only those things needed at runtime.
When pbrx build-images
is run in a project source
directory, the result will be a base image, named '{project}-base', and
then an image for each entry in
entry_points.console_scripts
with CMD
set to
that console script. For instance, in a python project "foo" that
provides console scripts called "foo-manage" and "foo-scheduler",
pbrx build-images
will result in container images called
"foo-base", "foo-manage" and "foo-scheduler".
pbrx build-images
uses volume mounts during the image
build process instead of copying to prevent wasted energy in getting
source code into the image and in getting artifacts out of the image.
This makes it well suited for use on laptops or in automation that has
access to something that behaves like a full computer but at the moment
less well suited for use in unprivileged container systems. Work will be
undertaken to remove this limitation.
Distro Depends
build-images
relies on bindep and
bindep.txt
to get the list of packages to install.
build-images
uses the Builder Image pattern so that one
image is used to make wheels of the project and its dependencies, and
another to install the package. Distro packages needed to build wheels
of a project or its python depends from source should be marked with a
compile
profile in bindep.txt
. Distro packages
needed at runtime should not be marked with a profile.
build-images
uses python:alpine
as a base
image. There are no plans or intent to make that configurable since
these are application images and the guest distro only serves to provide
Python and c-library depends. To mark dependencies in
bindep.txt
for images, the platform:apline
profile can be used.
The following is an example bindep file:
gcc [compile test platform:rpm platform:apk]
libffi-devel [compile test platform:rpm]
libffi-dev [compile test platform:dpkg platform:apk]
libffi [platform:apk]
libressl-dev [compile test platform:apk]
linux-headers [compile test platform:apk]
make [compile test platform:apk]
musl-dev [compile test platform:apk]
The only library needed at runtime is libffi
. The other
dependencies are all marked compile
so will be installed
into the build container but not the final runtime container. bindep is useful not
just for building containers, so entries for libffi-dev
on
debian as well as libffi-devel
on Red Hat are there. Also,
this example marks some packages as needed for test
. pbrx and bindep appropriately
ignore this information.
Note
Because of the use of the python:alpine
image, it is not
necessary to list python3-dev
in
platform:alpine
.
Python Dependencies
build-images
uses normal python mechanisms to get python
dependencies. Namely, it runs pip install .
in the mounted
source directory.
In most cases this is sufficient, but there are times when a single
set of dependencies for a set of console-scripts might not be
appropriate. In this case, it is possible to add a Python extra entry
for a console script to add additional python dependencies. For
instance, this section in setup.cfg
:
[extras]
zuul_base =
PyMySQL
psycopg2-binary
zuul_executor =
ara
Will cause PyMySQL
and psycopg2-binary
to
be installed into the base image (even though they are optional
dependencies for a normal install) and for ara
to be
installed in the zuul-executor
image.
Note
It is important to note that underscores must be used in the extras definition in place of dashes.