Click here to Skip to main content
15,037,928 members
Articles / Containers / Docker
Technical Blog
Posted 11 Jan 2021

Stats

2K views
1 bookmarked

Creating, Modifying and Updating Docker Image from Container

Rate me:
Please Sign up or sign in to vote.
4.00/5 (1 vote)
11 Jan 2021CPOL8 min read
How to create, modify and update Docker image from container
In this article, we will look at the process of creating image, running into container and modifying image and finally distributing the image using public repository and file-based approach.

Background

As part of Software development process, sometimes we need to configure containerize solution and create iterative improvement. In this process, a docker image is started with base image, and phase wise improvement is made by adding all the needed component to the image before finalizing the package. In that case, we start with bare metal image and continuously add additional layer in the process and pass the intermediate product to as different version. In this process, we must create image from a container after modifying the image and then pass the image along for further modification. In this article, we are going to look at the process of creating image, running into container and modifying image and finally distributing the image using public repository and file-based approach.

In addition to a will to go through this technical jargon, the following is needed to do hands on.

  • A Docker Hub account – A free registry account can be created at https://hub.docker.com/
  • Docker – Docker Desktop available at https://www.docker.com/products/docker-desktopcan be installed.
  • Terminal (e.g. PowerShell) - Any terminal can be used to execute docker command. In the example, we will be using PowerShell. In the PowerShell, $ is used to define a variable and # is used to start a comment

The command and example in these articles were made on Windows 10 machine with Windows PowerShell and Docker version 20.10.2.

Login to Docker Hub

Once the docker starts, we can login to the docker using DockerId. DockerID can be used as username while authenticating to a Docker registry for docker images. Docker client can be asked to connect to the registry to download or upload images. Docker Hub is one of the registries. An account can be created at https://hub.docker.com/.

Let’s start a PowerShell or Terminal window and log on using:

docker login --username benktesh #password will be entered in the prompt

When the above command is run and user is authenticated, a successful login prompt show.

Create Docker Image

Docker image can be created from scratch or we can use a publicly available image to get started. Here we are going to get an Ubuntu 18.04 image from Docker Hub with a pull command. Note that images can be created from the scratch. Please Creating Docker Image for an illusration about creating image.

Docker pull ubuntu:18.04

After the image has been pulled, we can verify that the image exists by executing image ls command.

Docker image ls

At the same time, if the docker desktop is installed, the list of images shows the existence of the image.

Run Image as Container

So far in the process, we have downloaded an image of Ubuntu 18.04 locally. This is similar to a situation we have got a Virtual Machine but is not running. To run this image, we need to run inside a container. The image can be run as container with the following command by specifying a name of the container suchas ‘ubuntu_container’ based on image ‘ubuntu’ with tag ’18.04’ as below:

docker run -d --name ubuntu_container -i -t ubuntu:18.04

--name argument is defining the name of the container and ubuntu:1804 is represent repository:tag information of the image. Argument -d ensures the container runs in detached mode. The above command can be made reusable by using variables. For example, in the PowerShell, we can define a variable for container name and image and use it.

$container = "ubuntu_container" #defines variable for container name

$image = "ubuntuL18:04" #defines a variable for image label

After such variables are defined, the command can use the variables as below:

docker run -d --name $container -i -t $image

The above command returns runs a container and returns the id of the container. We can check to see what is inside the container. To do this, we can open a bash shell in the container by executing

docker exec -it $container bash

which opens the bash prompt where we can execute cat /etc/os-release command to find out the release information on of the Ubuntu image that is running in the container. The result showed that we are running Version 18.04.5 (Bionic Beaver) of Ubuntu.

We verified that we Ubuntu 1804 is locally running as a container. Issuing exit command gets us out of the bash.

Modify Docker Image

After we have container running, we do ‘stuffs’ on it. For example, we add more layers and application to the container to make it more useful. For example, we could add one application and distribute the image with application to customers or provide it as a value-added image for later use. To mimic this, we are going to modify this container and create a new image out of this container and save to docker repository for public distribution.

For illustration, in the current container when we execute lsb_release -a, the response is that ‘command not found’ that means the container does not provide features for lsb_release. Next, we will update this container by adding lsb_release and make it re-usable for all the applications.

As part of the modification, we will update the base version, and install lsb_release package and mark the modification complete. We will first update the Ubuntu with apt update. Then we will install the lsb-core using apt install lsb-core. After the install completes, we can execute lsb_release -a to find the latest information about the Ubuntu.

We can now see that lsb_release -a is available. So essentially, we have made small update to the base Ubuntu image.

Like we installed lsb-core, applications can be installed in this image as part of the containerized solutions. To this document, we consider that we have now updated our image that can be reused by others thus is ready for distribution.

Create a New Image From Modified Container for Distribution

So far, we have got one image which is Ubuntu 18.04 that was pulled from the docker repository. We created a container and updated the images and installed lsb-core into that container. We inspect the status of images by executing docker images and status of container executing docker ps -a to see the list of images and containers, respectively. Note that ps stands for process status.

We can create a new image out of the currently running container image which includes the updates we have made by executing docker commit $container which returns sha256 string of the created image id. Executing docker images shows the newly created image with id of returned sha256. At this time, we have created a new image based on the updated container image.

We can tag the newly created image by providing an appropriate name. We will create a variable to store a new name ‘ubuntu_modified:18.04”

$newImage = "ubuntu_modified:18.04"

We will now commit to create a new image named ‘ubuntu_modified:18:04’.

docker commit $container $newImage

The command returns a sha hash to indicate the id of the newly created image. This image can be seen with docker images command

In the list we can see the newly created image named ‘ubuntu_modified’ with image id matching the sha256 identified and shows the time of creation. Note the size of the image – for new container – which is larger than the original image because we had installed new update to the image.

Now that we have created a fresh image out of the modified container, the older container can be removed. Frist we will stop the container and then remove it.

docker stop $container
docker rm $container

We will verify that the container indeed is removed by running docker ps command.

Now that we have deleted old container, we are going to create a new container named “modified_container” from the modified image. We can now run another container with newly created image. Let us create a new variable for new container

$newContainer = "modified_container"

Start a new container with:

docker run -d --name $newContainer -i -t $newImage

Open a bash shell on the newly created container.

docker exec -it $newContainer bash

After we execute lsb_release -acommand, note that the command returned the result without having to need for an update. Executing exit will get us out of the bash.

As before, lets stop and remove the newly created container as we do not need it.

docker stop $newContainer
docker rm $newContainer

Distributing Docker Image

Now that we have container image created, we are ready for distribution of the image. There are two ways to distribute the image. We can distribute it by pushing the image to public or private repository. For illustration, we are going to use Docker Hub Repository (https://hub.docker.com/repositories) to place the image for distribution.

Distribute using repository

First, we will tag the image to add the repository information. The docker.io is default repository. We will create a variable $repositoryTag to have a value of benktesh/ubuntu:1804 and tag the latest image and execute docker push command

$repositoryTag = "benktesh/ubuntu:18.04"
docker tag $newImage $repositoryTag
docker push $repositoryTag

and a simple docker push will the content to the outside world as it is publicly available in the repository which we can verify by going to the Docker Hub at navigating to benktesh/ubuntu(https://hub.docker.com/repository/docker/benktesh/ubuntu).

Now the file is in repository docker pull command can be used to get an image for further use.

Distribute by Creating Tar File

Another way is to create a tar file from either image or container. Here We are going to look at option where docker image can be saved as tar file.

docker save -o ubuntu.tar $repositoryTag

Command above creates a file ubuntu.tar with a tag defined in variable $repositoryTag which can distributed. The tar file can be loaded into docker to generate image with simple docker command as below:

docker load -i ubuntu.tar

Now the file is loaded, it can be used.

Conclusion

In this post, we illustrated how to create a docker image by using a base image from public repository, run that image in a container, and update the container with necessary installs and upgrades and then create an updated image from the containerized image modification. We also showed how to push the image to registry for distribution and looked at file-based approach to save and load images tar file.

Related Articles

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Benktesh Sharma
Engineer
United States United States
Benktesh is a senior software engineer at Sony where he is a software developer/architect. His main focus when coding is quality, simplicity, and scalability and he is experienced in a broad range of subjects (software design, software development process, project management, testing, UI, multithreading, database, mobile development, and more).

Outside of professional work, there are always some side projects he is working on such as simulation modeling of financial, energy and emissions data and writing articles both technical and non-technical (see his blog at https://benktesh.blogspot.com/). While not coding, he is either reading books fiction and/or non-fiction, watching tv shows, trading stocks, and discussing climate change, global warming, emission trading, and traveling to meet people, place, and culture.

Comments and Discussions

 
-- There are no messages in this forum --