dockerx is a tool which extends functionality of docker. This tool adds following enhancements:
- use volume mounts during build
- point to a custom Docker registry by default
- put build parameters into an options file
- override base image name during build
- patch existing images using command line instructions
- synchronize a resource in source image with target images
- flatten Docker images
- remove images based on regular expression
dockerx extends functionality of build, and adds commands patch and flatten. If command is not recognized by dockerx, it will pass the command with all arguments to regular docker tool.
dockerx build extends functionality of Docker's build process and adds ability to execute runtime instructions. From another side, same Dockerfile will work using regular "docker build".
In the Dockerfile, all commands below ###RUNTIME### comment line will be executed in runtime. It can be useful, for example, if source code is checked out as a part of the build process, and this Docker layer should not be cached.
Also, this command adds Docker's volume mount options -v and --volume to the build process. For example, "dockerx build -v ~/.gradle:/gradle -t chegg/myimage:latest ."
Docker's option "< <filename>" is not currently supported, this script requires a file named Dockerfile in the content folder, or "-f <filename>" option passed to run.
dockerx build supports all command line arguments of regular docker build command, excluding < <filename>.
Script parses given Dockerfile, and divides it into two separate files:
- df.c - static Dockerfile. Will be executed using regular "docker build" command. Image name passed using an option -t or --tag will be replaced with temporary UUID.
- df.sh - shell script which will be copied into the temporary image. Script name will match the temporary image name. This shell script contains all commands from the Dockerfile below the ###RUNTIME### line. When build is complete, dockerx will start a container based on the temporary image, and execute the shell script. After this, the container will be committed as a Docker image with a name specified in dockerx build command line.
Script supports all arguments of regular docker build command, and following additional arguments:
- -v, --volume: mount an external volume (see docker run docs for more details)
- --opts-file: loads command line arguments from a specified file; all arguments can be stored in opts file except path to Dockerfile
- --registry: use private registry instead of DockerHub without changing your Dockerfile; script will update base image name in FROM instruction, and will also apply new registry to the output image name
- --from: override base image name in your Dockerfile; script will replace base image name in FROM instruction. Can be combined with --registry
Commands CMD and ENTRYPOINT from the base imageby default will be overwritten during "docker commit". Because of this, **dockerx ** will duplicate these commands in commit instructions. If CMD or ENTRYPOINT is not specified in the Dockerfile, dockerx will inspect the base image to get these values.
Command ADD will be automatically moved to the static Dockerfile. To add files or folders from mounted volumes during runtime, use "RUN cp ..." instead.
If command USER switches user profile in the image, there is no way to return back to root profile in the runtime without entering sudo password. In this case, dockerx will analyze the static part of Dockerfile, will restore root session, and let the shell script know about another user profile.
Command ENV will be executed in the shell script as "export" command, and also it wil be added to "docker commit" command instructions.
Command dockerx build supports custom commands in Dockerfile. These commands must start with #! to be detected.
For example:
#!TAG my-image:latest
Implementation of these commands can be found in the utils/extras.py file. Custom commands can be extended by adding new functions with @docker annotation in utils/extras.py file. Function must have following format:
@docker def mycommand(params, context): #Some code here
Command will receive all arguments, and a context map which will contain image name and ID.
There is no need to register this command somewhere, it will be detected using @docker annotation. Command name in Dockerfile will match the function name in uppercase. In given example it will be
#!MYCOMMAND some parameters
Commands will be executed with their natural order. Methods can append context map to share data with other commands.
dockerx patch patches an existing image using Dockerfile instructions as command line arguments. It supports all arguments of dockerx build, and allows to pass multiple command instructions. Usage:
dockerx patch --command '<DOCKER-INSTRUCTION>' [--command '<DOCKER-INSTRUCTION>'...] <IMAGE_NAME>
dockerx will create a temporary folder, and save given instructions as a Dockerfile. It will ignore FROM instructions passed, and will use <IMAGE_NAME> as FROM as well as an output image name. After creating a Dockerfile, script will internally call dockerx build, and pass all arguments excluding --command.
dockerx sync will copy a resource (file or folder) from source image, and put it into all target images. If resource exists, it will be overwritten. Usage:
dockerx sync --source <SOURCE_IMAGE_NAME> --path <PATH_TO_RESOURCEgt; [--flatten=true] <TARGET_IMAGE_NAME> [<TARGET_NAME>...]
dockerx will create a temporary folder, run a container based on the source image, and copy the resource from the container into a temporary folder. Then it will patch each target image using dockerx patch to push the resource into these images. If --flatten flag is set to true, dockerx flatten will be called after patching.
dockerx flatten reduces size of Docker images. Usage:
dockerx flatten <IMAGE_NAME> [<TARGET_IMAGE_NAME>]
dockerx will inspect the source image, and extract the metadata. Then dockerx will start a new container based on the source image, export it using docker export, re-import it back as a target image. If target image name is not provided, dockerx will overwrite the source image. While importing, dockerx will apply the saved metadata.
dockerx rmi removes images based on a regex mask and exclude list. Usage:
dockerx [-x <EXCLUDED_IMAGE_NAME>] <IMAGE_NAME_MASK>
Example:
dockerx rmi -x my-project:latest my-project:.*
It supports all regular options of docker rmi.
dockerx will list all images, find matching names, exclude specified images, and will remove the rest.