This is a comprehensive container framework for generating multiple docker containers with the same configuration. It can be used to create containers for multiple versions of the same operating system or multiple operating systems with minimal effort.
It uses a core controller script along with a main template, a master config file and a packages config file for automatically identifying the correct versions for packages to be installed when generating the required Dockerfiles.
It will combine all of the above configuration to generate the required Dockerfiles and allow you to build them locally as well as publish them to both Docker Hub
and the Github Container Registry (GHCR)
. The repository also contains all of the workflows that you need to build and publish the containers automatically via Github Actions.
The framework attempts to support as many operating system distributions and versions as possible, but with the caveat that it will only use supported
versions of operating systems. Versions which have become end of life (EOL)
by the original vendor will get removed shortly after they go EOL
. It is however very simple to add additional versions or flavours if desired so if you have a specific need for an EOL'd version of an operating system is required little effort to reinstate it.
Operating System | Official Base Image | Our Tags |
---|---|---|
AlmaLinux 8 | Base Image | 8 & latest |
AlmaLinux 8 Minimal | Base Image | 8-minimal |
AlmaLinux 9 | Base Image | 9 |
AlmaLinux 9 Minimal | Base Image | 9-minimal |
Alpine 3.13 | Base Image | 3.13 |
Alpine 3.14 | Base Image | 3.14 |
Alpine 3.15 | Base Image | 3.15 |
Alpine 3.16 | Base Image | 3.16 & latest |
Amazon Linux 1 | Base Image | 1 |
Amazon Linux 2 | Base Image | 2 & latest |
Arch Linux | Base Image | base & latest |
Centos 7 | Base Image | 7 & latest |
Debian 10 (Buster) | Base Image | 10 & buster |
Debian 10 (Buster) Slim | Base Image | 10-slim & buster-slim |
Debian 11 (Bullseye) | Base Image | 11, bullseye & latest |
Debian 11 (Bullseye) Slim | Base Image | 11-slim & bullseye-slim |
Debian 12 (Bookworm) | Base Image | 12 & bookworm |
Debian 12 (Bookwork) Slim | Base Image | 12-slim & bookworm-slim |
Oracle Linux 7 | Base Image | 7 |
Oracle Linux 7 Slim | Base Image | 7-slim |
Oracle Linux 8 | Base Image | 8 |
Oracle Linux 8 Slim | Base Image | 8-slim |
Oracle Linux 9 | Base Image | 9 |
Oracle Linux 9 Slim | Base Image | 9-slim |
Photon 2.0 | Base Image | 2.0 |
Photon 3.0 | Base Image | 3.0 |
Photon 4.0 | Base Image | 4.0 & latest |
Rocky Linux 8 | Base Image | 8 |
Rocky Linux 8-minimal | Base Image | 8-minimal |
Rocky Linux 9 | Base Image | 9 |
Rocky Linux 9-minimal | Base Image | 9-minimal |
Scientific Linux 7 | Base Image | 7 & latest |
Ubuntu 14.04 (Trusty Tahr) | Base Image | 14.04 & trusty |
Ubuntu 16.04 (Xenial Xerus) | Base Image | 16.04 & xenial |
Ubuntu 18.04 (Bionic Beaver) | Base Image | 18.04 & bionic |
Ubuntu 20.04 (Focal Fossa) | Base Image | 20.04 & focal |
Ubuntu 22.04 (Jammy Jellyfish) | Base Image | 22.04, jammy & latest |
We use a generic programmatically derived name for each container to ensure consistency and uniqueness for all containers.
<container prefix>-<os>-<version> e.g. container-framework-debian-10
<docker hub org>/<container prefix>-<os>:<version> e.g. wolfsoftwareltd/container-framework-debian:10
or
ghrc.io/<github org>/<container prefix>-<os>:<version> e.g. ghcr.io/dockertoolbox/container-framework-debian:10
The container names are dynamically generated based on the directory tree. All of the files are situated below the Dockerfiles directory (see below). The next level is the operating system name and the final level is the operating system version. This is used internally by the container framework to known which docker container to pull and use as the base and the target OS/version for the built container. There are other files and directories within the tree but not shown on the diagram below. The main other folder is Templates
which is a sub folder of each OS version folder and this contains symlinks to the relevant template files (more on that later).
Dockerfiles
├── almalinux
│ ├── 8
│ ├── 8-minimal
│ ├── 9
│ └── 9-minimal
├── alpine
│ ├── 3.13
│ ├── 3.14
│ ├── 3.15
│ └── 3.16
├── amazonlinux
│ ├── 1
│ └── 2
├── archlinux
│ └── base
├── centos
│ └── 7
├── debian
│ ├── 10
│ ├── 10-slim
│ ├── 11
│ ├── 11-slim
│ ├── 12
│ └── 12-slim
├── oraclelinux
│ ├── 7
│ ├── 7-slim
│ ├── 8
│ ├── 8-slim
│ ├── 9
│ └── 9-slim
├── photon
│ ├── 2.0
│ ├── 3.0
│ └── 4.0
├── rockylinux
│ ├── 8
│ ├── 8-minimal
│ ├── 9
│ └── 9-minimal
├── sl
│ └── 7
└── ubuntu
├── 14.04
├── 16.04
├── 18.04
├── 20.04
└── 22.04
If you want to use this container framework to develop your own Docker containers there are 4 core files that you will to update.
The configuration file handles various configuration components that are required either during the generate, build or publish phase. The first half of the file manages the generic container configuration. E.g. which Docker Hub org to publish under, what GitHub org to publish under, what github repo the containers are in etc.
# Required for generate & build phase
CONTAINER_PREFIX='' # Prefix to use when creating / publishing the containers
# Required for publish phase
DOCKER_HUB_ORG='' # Dockerhub org to publish under
GHCR_ORGNAME='' # Github org to publish packages under
# Required for Single OS usage only
SINGLE_OS=false
SINGLE_OS_NAME=''
NO_OS_NAME_IN_CONTAINER=false
The second half only needs to be touched if you are planning to create containers for a single OS and remove the OS name from the directory tree. An example of this is our alpine-bash containers. As you can see below the directory tree under Dockerfiles only contains the OS version and the operating system name is configured in the config.cfg.
Dockerfiles
├── 3.13
├── 3.14
├── 3.15
└── 3.16
The packages file lists all of the packages that you want/need to install during the creation of the containers. This is used during the generate phase to select the correctly versioned package for the container you are building. Simply list the package names and let the generate stage do the rest. The generate phase makes use of our version helper code to correctly identify the specific version of the package in relation to the specific version of the operating system within the container. This might be considered overkill as you could simply install based on the package name but we wanted to go one step further and installed the latest specific versioned package.
As per the documentation from the version helper repository, configuration can done in one of two ways:
This is the default and the code attempts to work out which package manager is available for a given operating system and then used the correct list of packages.
APK_PACKAGES= # Alpine Packages
APK_VIRTUAL_PACKAGE= # Alpine Virtual Packages (These are not versioned)
APT_PACKAGES= # Debian / Ubuntu Packages
PACMAN_PACKAGES= # Arch Linux
TDNF_PACKAGES= # Photon Packages
YUM_PACKAGES= # AlmaLinux / Amazon Linux / Centos / Oracle Linux / Rocky Linux / Scientific Linux
YUM_GROUPS= # Yum Groups
Oracle Linux 8 slim comes with
microdnf
instead ofyum
but we simply install yum usingmicrodnf
and then carry on as normal.
DISCOVER_BY=OS # Tell the version-grabber to use Operating System ID instead of package manager
ALMA_PACKAGES= # AlmaLinux Packages
ALPINE_PACKAGES= # Alpine Packages
ALPINE_VIRTUAL_PACKAGES= # Alpine Virtual Packages (These are not versioned)
AMAZON_PACKAGES= # Amazon Linux Packages
ARCH_PACKAGES= # Arch Linux Packages
CENTOS_PACKAGES= # Centos Packages
DEBIAN_PACKAGES= # Debian Packages
ORACLE_PACKAGES= # Oracle Linux Packages
PHOTON_PACKAGES= # Photon Linux Packages
ROCKY_PACKAGES= # Rocky Linux Packages
SCIENTIFIC_PACKAGES= # Scientific Linux Packages
UBUNTU_PACKAGES= # Ubuntu Packages
The labels file is used to define what static labels should be added to the Dockerfile. You can add more labels if you wish or remove any that you do not feel are required. If you want to remove all of the static labels then you can simple remove the labels file. However we recommend that as a minimum
you retain at least the license
and created
labels.
LABEL org.opencontainers.image.authors=''
LABEL org.opencontainers.image.vendor=''
LABEL org.opencontainers.image.licenses=''
LABEL org.opencontainers.image.title=''
LABEL org.opencontainers.image.description=''
LABEL org.opencontainers.image.created="$(date --rfc-3339=seconds --utc)"
In addition to the above static labels we also add the following dynamic
labels
LABEL org.opencontainers.image.source=${GIT_URL}
LABEL org.opencontainers.image.documentation=${GIT_URL}
The
${GIT_URL}
is automatically calculated by processing the git origingit config --get remote.origin.url
The install template is the file that contains the commands that are generic to all the containers being build and contains the commands that install and configure the items that exist in the container. This is symlinked from each container directory.
The Dockerfile Template is the main template file which is used in conjunction with the other config files mentioned above to generate the actual Dockerfile used to build the containers. The file is a very simple template.
FROM ${CONTAINER_OS_NAME}:${CONTAINER_OS_VERSION_ALT}
${LABELS}
RUN \
${PACKAGES}
${INSTALL}
${CLEANUP}
WORKDIR /root
ENTRYPOINT ["/bin/bash"]
The same file is used for all the containers and the valuables as substituted when the container is generated.
There is a cleanup symlink in each container directory which points to the correct cleanup script, this removes any packages that are no longer required and also removes packages caches and other general good practice cleanup operations.
File | Purpose |
---|---|
apk-cleanup.tpl | Cleanup for Alpine based containers. |
apt-cleanup.tpl | Cleanup for Debian / Ubuntu based containers. |
microdns-cleanup.tpl | Cleanup for Oracle Linux slim based containers. |
pacman-cleanup.tpl | Cleanup for Arch Linux based containers. |
tdnf-cleanup.tpl | Cleanup for Photon Linux based containers. |
yum-cleanup-with-leaves.tpl | Cleanup for Amazon Linux, Centos 7 and Scientific Linux based containers. |
yum-cleanup.tpl | Cleanup for AlmaLinux, Oracle Linux (excluding 8-slim) and Rocky Linux based containers. |
We do supply Dockerfiles within the repository, these Dockerfiles are dynamically generated using a helper script which is also supplied. The helper script is called manage-all.sh
and can be from any level of the directory tree and is recursive.
If you are in the top level directory you will need to use
manage.sh
instead ofmanage-all.sh
-h | --help : Print this screen
-d | --debug : Debug mode (set -x)
-b | --build : Build a container (Optional: -c or --clean)
-g | --generate : Generate a Dockerfile
-p | --publish : Publish a container
-G | --ghcr : Publish to Github Container Registry
-t | --tags : Add additional tags
These options are available at any level of the directory tree.
./manage-all.sh --generate
./manage-all.sh --build [--clean]
./manage-all.sh --publish [ --ghcr ]
It is possible to generate, build and publish all of the above containers at the same time.
./manage-all.sh --generate --build --clean --publish