I want to share an idea I have with you. It's a simple one, so it won't take long.
When I'm explaining to a colleague the idea of Containers and Docker (when they don't have any previous knowledge), I often use programming terminology—it's easier for me to explain it like that. So, images are like classes and containers are like objects. I can inherit from an image to create a new image, and logically, it's like extending a Java class.
Similarly, I may want to introduce the "Abstract Image" term—an image that includes most of the functionality, but is not runnable. This image will be used to create new runnable images.
Why do I need it? Well, I guess I can solve my problems in many ways, but I found this one fits my needs. Who knows, it might serve you as well.
I have a backend RESTful server that is deployed on many customers' sites. Each deployment has different configuration files to control the server behavior, the set of features that are enabled, and possibly even the data model.
Now, we want to move to Docker. So, I built an abstract image of my server software without any configurations, and I'm using that to create an image per distinct customer. These images are super lightweight–they only contain the configuration files.
The way to build an abstract image is to use the combination of the ONBUILD and the ENTRYPOINT Dockerfile instructions. I didn't find an example of such a combination in the Dockerfile documentation, but it works!
ONBUILD is a Dockerfile instruction that performs the following instruction in the file only when using the image as a base to create a new image.
Using this instruction with the ENTRYPOINT instruction causes the entry point to execute only in the new derived image creation.
So, if I have the Dockerfile, and I build the "base_app" image from it:
# base_image:2.34 FROM centos_6_java8:1.1 WORKDIR /opt/myapp EXPOSE 1234 # adding the softwar, environment variables and a run.sh script to run the software # ... USER myappuser ONBUILD ENTRYPOINT ./run.sh
Now, I can use this image as a base for a new customer specific runnable images:
# customer_specific_image FROM base_app:2.34 ADD customer_specific_configurations.tar
And, that's it. I don't need to repeat the running environment and parameter for each image—it's all there from the base_app image. Now, each container created from the project specific image will run the script from the base_image.