docker_wrapper User Guide
Installation
First, create and activate a Python virtual environment:
python3 -m venv venv
source venv/bin/activate
Then install the docker_wrapper package:
pip install .
When you are actively developing the module code use the -e option to
install the project in editable mode and allow code development
pip install -e .
The above install steps are automated through the make install command.
To interact with the CLI you still need to activate the new environment by doing
source vevn/bin/activate
# Run the help command of the docker wrapper
./venv/bin/docker_wrapper --help
Overview
The goal of this library is to provide a convenient wrapper around Docker to allow us to perform common development and CI tasks. The intent is to have a number development Docker images that can enable us to have reproducible builds.
The type of tasks we want to be able to automate are:
- Build the docker images, and enable introducing a "hierarchy" of images where common dependencies are factored out.
- Pull / push docker images to the docker registries, which could be multiple based on our CI needs.
- Create development container that the user can work side
- Allow to run commands inside temporary containers that could be used in our CI.
Code Organization
We are providing a common Docker library called docker_wrapper
where we have a base class DockerImage that implements the basic wrapper logic.
A CLI interface is implemented under cli.py the user can call function
create_cli to register a CLI in the target's repos entrypoint helper script.
Usage Mode
The intent is for this library to be part of requirements.txt file of each repo and be consumed
by the repo-cli.py script ( or any other entrypoint script ) of the repo. Then in each repo
we are doing to define a docker-images folder, similar to sample-images folder of
this folder.
Docker-Image Folder Layout
The expectation is that the docker-images folder contains a single-level hierarchy of folder, where
each folder has the following layout:
ubuntu_base/
├── Docker
│ ├── Dockerfile
│ └── entrypoint.sh
├── docker_wrapper_extensions.py
├── __init__.py
Each docker image has a script called docker_wrapper_extensions.py where we implement "logic" specific
to that docker image. Inside that file we are defining a DockerImage class as follows:
import os
from typing import List
import docker_wrapper
class DockerImage(docker_wrapper.DockerImage):
"""ubuntu_base docker image
Args:
docker_wrapper (_type_): Parent class
"""
def __init__(self) -> None:
super().__init__()
self.name = "ubuntu_base"
self.docker_folder = os.path.realpath(
os.path.join(os.path.realpath(__file__), "../Docker")
)
print(self.docker_folder)
We also expect that there is a Docker folder where we have the Dockerfile and anyother script (e.g. entrypoint.sh)
that we want to be added to the Docker image.
Image registration
In cli.py we provide function create_cli to "register" any images that we have available.
The create_cli takes as an argument the path of the top-level folder where all images are located. It expects that
it would find per image a file layout similar to the one described above. create_cli checks that there is a Docker subfolder
per image and import the docker_wrapper_extensions.py file of each image, find the DockerImage class and "register" it with
the rest of the CLI commands.