One of the cool things about Docker is that you can make changes to a Docker container from an existing Docker image (for example, deploy your applications, fine-tune your configurations, etc) and then save (or “commit”) the changes into your own Docker image. You can also push the images into Docker Hub repository, which is available for all Docker users, free of charge. You just need to create an account, then create a repository for storing (pushing) your images within the Docker Hub portal. You can set your repository to be public (for others to be able to pull your images) or private (only you can acess the repository).
The article below contains step-by-step instructions for building your own Docker image from an existing image using two different methods: the manual method using “docker commit” and the automated method using a Dockerfile. Lastly, there are also step-by-step instructions on how you can push your own Docker image into Docker Hub repository.
You may also refer to our previous articles on how to pull existing Docker images and run the Docker container on top of the existing image. Similar to our earlier articles, the command examples here were done on an Ubuntu virtual machine hosted in SimplerCloud, although the same commands will also work on Docker running on any other platforms (such as CentOS, Fedora, Debian etc). Since root account was being used, sudo command was omitted on most of the steps. If you are using a non-root user with sudo access on a Debian or Ubuntu environment, please append sudo in front of each command (e.g. sudo docker images instead of docker images).
Managing Existing Images
You can list the existing images you have locally on your server by using docker images command
We can see that in addition to the default hello-world Docker image, there’s an existing “ubuntu:latest” image which we previously used on the earlier article. Take note that a repository might have different variants of an image, for example, the “ubuntu” repository might have different images covering different versions of Ubuntu, e.g. “ubuntu:14.04”, “ubuntu:12.04”, etc. Note that the tag identifies the different Ubuntu versions, and if we don’t specify the variant, then Docker will by default use the “ubuntu:latest” image as per the above example.
Since Docker recommends us to specify an image tag to differentiate the different variants/versions of the image we are using, let’s pull a new existing image by specifying the tag, to ensure that we know which version of Ubuntu OS we will be working on. We will use the latest Ubuntu LTS version at the time of writing this article, which is Ubuntu version 14.04. Use this command: docker pull ubuntu:14.04 to pull the latest image of the Ubuntu 14.04 variant.
Let’s verify that the new image is being pulled properly by using the docker images command
From the above example, we can see that the new image has been pulled successfully and we shall use this newly pulled image as a base to create a new image.
Build Your Own Docker Images
While you might find the default image provided by Docker (e.g. the “ubuntu:14.04” image above) to be suitable and useful for most cases, there will be times when you would need to make some modifications to the image to better suit your application’s needs. There are two different methods on how you can update (that is, make the necessary changes) and then create a new Docker image with the changes:
- Create a container from the existing image, make changes and update the container, and then commit the result to a new image; or
- Use a “Dockerfile” to specifically provide instructions on how to update and create a new image.
Let’s start with the first method first.
1. Updating and Committing an Image
Before you can update an image, you would need to create a new Docker container, from the image you want to update. Use below command to create a new Docker container from the existing Ubuntu:14.04 image: docker run -t -i ubuntu:14.04 /bin/bash
We can see that a new container has been created out of the existing image and we are being redirected to the shell prompt of the new container. You can make some additional changes to the container, for example for you to install additional packages required by your application development. On this example, we will run “apt-get update” and “apt-get dist-upgrade” to install the latest patches for Ubuntu, and then install MySQL package (for example, if MySQL is required by your application).
Take note of the container ID shown on the shell prompt. On the above example, the container ID is 991f36df0863. You would need this container ID when you commit this container into a new image later.
Let’s start with running apt-get update first.
And then continue with running apt-get dist-upgrade to install all the latest patches for Ubuntu
Let’s continue with installing MySQL (note that this is just an example, you can install any packages you need for your application). Use apt-get install mysql-server command to install MySQL on the container that you have.
Note that during MySQL installation process, you will be prompted for the MySQL root password you want to use. Please key in the root password you intend to use.
Complete the MySQL installation.
You can verify that the MySQL server has been installed by running service mysql status command. Based on below result, we can see that the MySQL server is already installed, although it’s still on stopped state.
To start the MySQL server, run the service mysql start command
Verify again that the MySQL service has been started by running the same service mysql status command
Congratulations, you have installed MySQL Server package on the container. The next step would be to save the container as a new Docker image. The first thing you need to do is to exit the container by typing the exit command
You will be transported back to the parent server’s shell prompt, and you now have a container which you have updated and ready to be committed as a new Docker image. To check and confirm the container ID again, use the docker ps -a command
Based on the above, we can see that the container ID which we want to save as a new Docker image is 991f36df0863. Use below docker commit command to save (or commit) the container into a new Docker image:
docker commit -m “Install MySQL” -a “SimplerCloud” 991f36df0863 simplercloud/ubuntu:14.04v2
Note that there are two flag options being specified: “-m” and “-a”. The “-m” option allows you to specify a commit message for easy identification (e.g. “Install MySQL”) while the “-a” option allows you to include an author / name of the person or entity who made the commit. You also need to specify the container ID which you want to be committed to the new image (991f36df0863 for the above example). You also need to specify the target name for the image, on the above example, “simplercloud” is a new repository user you have created while “ubuntu” is the image name. “14:04v2” is the new tag you have specified for this new image.
Verify that the new images has been committed / saved by using the docker images command.
Based on the above result, we can see that the new image has been created under “simplercloud/ubuntu” repository and “14.04v2” tag, with image ID: cf58c3358c9e. You may also notice that the size of the image is bigger, due to the additional package you have installed.
2. Building an Image from a Dockerfile
The second method of builing a new Docker image is to use a “Dockerfile”, a file which contains a set of instructions to tell Docker how to build the new image. First, please create a directory, go into the directory and create a Dockerfile within the directory using your favourite Linux text editor (vi or nano).
mkdir simplercloud – to create a directory named “simplercloud”
cd simplercloud – to enter the newly created directory
vi Dockerfile or nano Dockerfile – to use your favourite Linux text editor (vi or nano) to create the Dockerfile.
For example, here is the set of instructions we want to put into the Dockerfile:
#My first Dockerfile
MAINTAINER SimplerCloud <firstname.lastname@example.org>
RUN apt-get update && apt-get dist-upgrade -y
RUN apt-get install mysql-server -y
Note that you can add a comment line within the Dockerfile by adding a “#” in front of the line. The first instruction: “FROM” is to tell Docker which image we want to use as the base image for building the new image, in the above example, we plan to use the original “ubuntu:14.04” image as a base.
The “MAINTAINER” line specifies which user will maintain the new image, while the set of “RUN” instructions tell Docker what are the commands to be executed within the original image container to make the new image. On the above example, we will run the same commands as per the earlier method, which is to install the latest patches and to install the MySQL server package. Note that the “-y” flag is being used to prevent user prompt which will break the automated process. Save the Dockerfile once done.
Next, try to build a new image based on the Dockerfile which you have created. Use the “docker build” command as follows:
docker build -t simplercloud/ubuntu:14.04v3 .
Take note the trailing dot (.) after the image name. That is to specify the location of the Dockerfile. Since you are running the docker build command on the same directory where the Dockerfile is being located, you can just put a dot (.) there. Otherwise, you would need to specify the exact location of the Dockerfile, for example: docker build -t simplercloud/ubuntu:14.04v3 /root/simplercloud/Dockerfile.
Wait until the build process is completed. Note that Docker is able to get around the prompt for MySQL root password during MySQL server package installation. Once the image is built successfully, you will see “Successfully built (image ID)” message.
You can see that the new image has been successfully built with image ID: 1410f427f14c. You can verify using docker images command to verify
To verify that your new image is working fine, just create a container using the new image: docker run -t -i simplercloud/ubuntu:14.04v3 /bin/bash
Within the new container, check if MySQL is installed. If it’s stopped, try to start it. If MySQL is started, that means the build process is successful
Congratulations, you have managed to build a new image using the two methods.
Push Image to Docker Hub
Last but not least, you can push your newly created images to Docker Hub registry using docker push command. You can either share your images publicly, or alternatively you can also push your images into a private repository within Docker Hub. Take note that you would need to create a user ID within Docker Hub portal. Once you have created the Docker Hub account and have your email address verified, login to the Docker Hub portal and create the necessary repository for you to push your Docker images into.
From your server running Docker, you can login to your Docker Hub account by using the docker login command. Key in the username, password and email address you use for your Docker Hub account.
To push an image, use below command:
docker push simplercloud/ubuntu:14.04v3
The above command will push the newly image that you created earlier, into your repository on Docker Hub.
You can then verify by logging into your Docker Hub portal to verify that the image is already there.
Congratulations, you have just pushed your own images into the Docker Hub repository.
Index of Docker articles :
Disclaimer : This is another great guest post article by Indra Pramana from SimplerCloud.com, a cloud servers provider from Singapore with solutions built from the ground up to provide truly real-time, scalable and easily managed cloud infrastructure for start-ups, developers and business throughout Asia.