This is in continuation of my last blog “9. DevOps: How to do Containers housekeeping ?”. In this blog I would like to demonstrate on:
How to Build images from docker containers?:
Note: If you want to recollect the docker commands to be used during your current lab practice, visit my blog link:
So far we have built the containers and operated them through the previous exercises. Now, let us see how can we add software to our base image on a running container and then convert that container into an image for future usage.
Let’s take ubuntu:16.04 as our base image, install the wget application, and then convert the running container to an image with the below steps:
To make ubuntu:16.04 container is our base image, we need to install the wget application, and then convert it as the running container to a docker image by using the below steps:
- Launch an ubuntu:16.04 container using the docker run subcommand, as shown below:
$ sudo docker run -i -t ubuntu:16.04 /bin/bash ========================> vskumar@ubuntu:~$ sudo docker ps -aq 155f4b0764b1 vskumar@ubuntu:~$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 155f4b0764b1 ubuntu:16.04 "/bin/bash" 2 hours ago Up 11 minutes zen_volhard vskumar@ubuntu:~$ sudo docker run -i -t ubuntu:16.04 /bin/bash root@3484664d454a:/# =========================> 2. Now, let's verify is wget available for this image or not. ============== the display shows there is no wget in this image =========> root@3484664d454a:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@3484664d454a:/# which wget root@3484664d454a:/# root@472c96295678:/# apt-get update ==================> As we know that it is a brand new ubuntu container we built it, before installing wget we must synchronize it with the Ubuntu package repository, as shown below: ====================> root@3484664d454a:/# apt-get update Get:1 http://archive.ubuntu.com/ubuntu xenial InRelease [247 kB] Get:2 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB] Get:3 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB] Get:4 http://archive.ubuntu.com/ubuntu xenial-backports InRelease [102 kB] Get:5 http://archive.ubuntu.com/ubuntu xenial/universe Sources [9802 kB] Get:6 http://security.ubuntu.com/ubuntu xenial-security/universe Sources [53.1 kB] Get:7 http://security.ubuntu.com/ubuntu xenial-security/main amd64 Packages [504 kB] Get:8 http://security.ubuntu.com/ubuntu xenial-security/restricted amd64 Packages [12.9 kB] Get:9 http://security.ubuntu.com/ubuntu xenial-security/universe amd64 Packages [229 kB] Get:10 http://security.ubuntu.com/ubuntu xenial-security/multiverse amd64 Packages [3479 B] Get:11 http://archive.ubuntu.com/ubuntu xenial/main amd64 Packages [1558 kB] Get:12 http://archive.ubuntu.com/ubuntu xenial/restricted amd64 Packages [14.1 kB] Get:13 http://archive.ubuntu.com/ubuntu xenial/universe amd64 Packages [9827 kB] Get:14 http://archive.ubuntu.com/ubuntu xenial/multiverse amd64 Packages [176 kB] Get:15 http://archive.ubuntu.com/ubuntu xenial-updates/universe Sources [228 kB] Get:16 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages [864 kB] Get:17 http://archive.ubuntu.com/ubuntu xenial-updates/restricted amd64 Packages [13.7 kB] Get:18 http://archive.ubuntu.com/ubuntu xenial-updates/universe amd64 Packages [711 kB] Get:19 http://archive.ubuntu.com/ubuntu xenial-updates/multiverse amd64 Packages [18.5 kB] Get:20 http://archive.ubuntu.com/ubuntu xenial-backports/main amd64 Packages [5174 B] Get:21 http://archive.ubuntu.com/ubuntu xenial-backports/universe amd64 Packages [7135 B] Fetched 24.6 MB in 59s (412 kB/s) Reading package lists... Done root@3484664d454a:/# ================================> Now, we can install wget as below: =========== Output of wget installation on container ===========> root@3484664d454a:/# root@3484664d454a:/# apt-get install -y wget Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: ca-certificates libidn11 libssl1.0.0 openssl The following NEW packages will be installed: ca-certificates libidn11 libssl1.0.0 openssl wget 0 upgraded, 5 newly installed, 0 to remove and 1 not upgraded. Need to get 2089 kB of archives. After this operation, 6027 kB of additional disk space will be used. Get:1 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 libidn11 amd64 1.32-3ubuntu1.2 [46.5 kB] Get:2 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 libssl1.0.0 amd64 1.0.2g-1ubuntu4.9 [1085 kB] Get:3 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 openssl amd64 1.0.2g-1ubuntu4.9 [492 kB] Get:4 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 ca-certificates all 20170717~16.04.1 [168 kB] Get:5 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 wget amd64 1.17.1-1ubuntu1.3 [299 kB] Fetched 2089 kB in 4s (421 kB/s) debconf: delaying package configuration, since apt-utils is not installed Selecting previously unselected package libidn11:amd64. (Reading database ... 4768 files and directories currently installed.) Preparing to unpack .../libidn11_1.32-3ubuntu1.2_amd64.deb ... Unpacking libidn11:amd64 (1.32-3ubuntu1.2) ... Selecting previously unselected package libssl1.0.0:amd64. Preparing to unpack .../libssl1.0.0_1.0.2g-1ubuntu4.9_amd64.deb ... Unpacking libssl1.0.0:amd64 (1.0.2g-1ubuntu4.9) ... Selecting previously unselected package openssl. Preparing to unpack .../openssl_1.0.2g-1ubuntu4.9_amd64.deb ... Unpacking openssl (1.0.2g-1ubuntu4.9) ... Selecting previously unselected package ca-certificates. Preparing to unpack .../ca-certificates_20170717~16.04.1_all.deb ... Unpacking ca-certificates (20170717~16.04.1) ... Selecting previously unselected package wget. Preparing to unpack .../wget_1.17.1-1ubuntu1.3_amd64.deb ... Unpacking wget (1.17.1-1ubuntu1.3) ... Processing triggers for libc-bin (2.23-0ubuntu9) ... Setting up libidn11:amd64 (1.32-3ubuntu1.2) ... Setting up libssl1.0.0:amd64 (1.0.2g-1ubuntu4.9) ... debconf: unable to initialize frontend: Dialog debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76.) debconf: falling back to frontend: Readline debconf: unable to initialize frontend: Readline debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.22.1 /usr/local/share/perl/5.22.1 /usr/lib/x86_64-linux-gnu/perl5/5.22 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.22 /usr/share/perl/5.22 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base .) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.) debconf: falling back to frontend: Teletype Setting up openssl (1.0.2g-1ubuntu4.9) ... Setting up ca-certificates (20170717~16.04.1) ... debconf: unable to initialize frontend: Dialog debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76.) debconf: falling back to frontend: Readline debconf: unable to initialize frontend: Readline debconf: (Can't locate Term/ReadLine.pm in @INC (you may need to install the Term::ReadLine module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.22.1 /usr/local/share/perl/5.22.1 /usr/lib/x86_64-linux-gnu/perl5/5.22 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.22 /usr/share/perl/5.22 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base .) at /usr/share/perl5/Debconf/FrontEnd/Readline.pm line 7.) debconf: falling back to frontend: Teletype Setting up wget (1.17.1-1ubuntu1.3) ... Processing triggers for libc-bin (2.23-0ubuntu9) ... Processing triggers for ca-certificates (20170717~16.04.1) ... Updating certificates in /etc/ssl/certs... 148 added, 0 removed; done. Running hooks in /etc/ca-certificates/update.d... done. root@3484664d454a:/# =========================== End of installation ===========> Now, we can verify with 'which wget ' command ============> root@3484664d454a:/# which wget /usr/bin/wget root@3484664d454a:/# ============> Please let us recollect; installation of any software would alter the Dockwer base image composition. In which, we can also trace using the docker diff subcommand as we did in the previous exercises. I will open a second Terminal/screen, the docker diff subcommand can be issued from it, as below: $ sudo docker diff 472c96295678 ===============> vskumar@ubuntu:~$ vskumar@ubuntu:~$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3484664d454a ubuntu:16.04 "/bin/bash" 15 minutes ago Up 15 minutes jolly_cray 155f4b0764b1 ubuntu:16.04 "/bin/bash" 2 hours ago Up 40 minutes zen_volhard vskumar@ubuntu:~$ sudo docker diff 155f4b0764b1 C /root A /root/.bash_history vskumar@ubuntu:~$ ============> How to save this container ?: The docker commit subcommand can be performed on a running or a stopped container. When a commit is performed on a running container, the Docker Engine pauses the container during the commit operation in order to avoid any data inconsistency. Now we can stop our running container. We can commit a container to an image with the docker commit subcommand, as shown here: $ sudo docker commit ================== Using commit for container ============> root@3484664d454a:/# root@3484664d454a:/# exit exit vskumar@ubuntu:~$ sudo docker commit 3484664d454a [sudo] password for vskumar: Sorry, try again. [sudo] password for vskumar: sha256:fc7e4564eb928ccfe068c789f0d650967e8d5dc42d4e8d92409aab6614364075 vskumar@ubuntu:~$ =======================> You can see the container id from the above output. =========== We can also give a message to the commit command as below ===> vskumar@ubuntu:~$ sudo docker commit 3484664d454a Docker-exercise/ubuntu-wgetinstall invalid reference format: repository name must be lowercase vskumar@ubuntu:~$ sudo docker commit 3484664d454a docker-exercise/ubuntu-wgetinstall sha256:e34304119838d79da60e12776529106c350b1972cd517648e8ab90311fad7b1a vskumar@ubuntu:~$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3484664d454a ubuntu:16.04 "/bin/bash" 24 minutes ago Exited (130) 6 minutes ago jolly_cray 155f4b0764b1 ubuntu:16.04 "/bin/bash" 2 hours ago Up About an hour zen_volhard vskumar@ubuntu:~$ ===================== Note there are two containers created ====> Now, I want to remove one container : ==========> vskumar@ubuntu:~$ sudo docker rm 3484664d454a 3484664d454a vskumar@ubuntu:~$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 155f4b0764b1 ubuntu:16.04 "/bin/bash" 3 hours ago Up About an hour zen_volhard vskumar@ubuntu:~$ ========================> Now let us check the docker images how many we have in our store : =========== List of images ==========> vskumar@ubuntu:~$ vskumar@ubuntu:~$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker-exercise/ubuntu-wgetinstall latest e34304119838 5 minutes ago 169MB <none> <none> fc7e4564eb92 7 minutes ago 169MB hello-world latest f2a91732366c 5 days ago 1.85kB ubuntu 16.04 20c44cd7596f 8 days ago 123MB ubuntu latest 20c44cd7596f 8 days ago 123MB busybox latest 6ad733544a63 3 weeks ago 1.13MB busybox 1.24 47bcc53f74dc 20 months ago 1.11MB vskumar@ubuntu:~$ ==============================> How to remove images:
by using :
sudo docker rmi image [image id], we can remove the image. For example; if you want to remove the image id:
47bcc53f74dc
you can use: $ sudo docker rmi image 47bcc53f74dc
=================>
vskumar@ubuntu:~$ sudo docker rmi image 47bcc53f74dc
Untagged: busybox:1.24
Untagged: busybox@sha256:8ea3273d79b47a8b6d018be398c17590a4b5ec604515f416c5b797db9dde3ad8
Deleted: sha256:47bcc53f74dc94b1920f0b34f6036096526296767650f223433fe65c35f149eb
Deleted: sha256:f6075681a244e9df4ab126bce921292673c9f37f71b20f6be1dd3bb99b4fdd72
Deleted: sha256:1834950e52ce4d5a88a1bbd131c537f4d0e56d10ff0dd69e66be3b7dfa9df7e6
Error: No such image: image
vskumar@ubuntu:~$
=================>
So by using :
sudo docker rmi image [image id], we can remove the image.
Just recollect the difference between the image removal and container removal. For containers removal refer to my blog on "Housekeeping containers". Now we have learned how to create an image from containers using a few easy steps by installing the wget application. You can also add some other software applications to the same or different container(s) in the similar way.
You can use this method for testing also. Let us say, you want to test a set of java programs. Then you need to install jdk and copy your programs. Write a shell script to compile and execute the programs by piping their output into a text file in a Linux background. So this way, you will be using the container as a test environment also.
The most easy and recommended way of creating an image is to use the Dockerfile method.
Within dockerfile we can mention the setup required to build a container through different steps. Then dockerfile creates the required setup for a container, under docker’s building activity.
We will see it in future exercises.
Please leave your feedback!
9. DevOps: How to do Containers housekeeping ?