In our previous post we get introduction about docker and how we could install it on CentOS and Ubuntu Linux machines. In this post we would try to cover further aspects of docker and its images like.
Docker_docs
How to download or get Docker images and How to Start/Stop docker container from images.

In this setup we are working on Ubuntu 16.04 Host machine and docker Server version 17.03

Setup

#lsb_release -d
Description:	Ubuntu 16.04.2 LTS

#docker info| grep Server
Server Version: 17.03.1-ce

Pull Docker images

To work for docker containers, we have to get docker images. By default, it downloads from Docker Hub. This is docker registry managed by Docker company that work for Docker project.
Anyone can have a login on Docker website and can upload their images which further accessible from worldwide.

We can search various docker images with docker search command. This command will provide you a list of images contain string used to search.

#docker search ubuntu

You can pull those images with their names through pull sub-command.

docker pull ubuntu

Once image has been downloaded, we can use those images in docker containers with docker sub-command run.

# docker run -it ubuntu /bin/bash
root@7859a24d72e9:/# cat /etc/issue
Ubuntu 16.04.2 LTS \n \l

In above command, we used docker run command with -i and -t options to connect Ubuntu container /bin/bash shell

-i, --interactive                    Keep STDIN open even if not attached
-t, --tty                            Allocate a pseudo-TTY

We can see all images downloaded with docker sub-command (docker images) and see containers with sub-command (docker ps) in host machine.

#docker images ubuntu
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              15.04               d1b55fd07600        17 months ago       131MB


#docker ps -a
CONTAINER ID    IMAGE   COMMAND                  CREATED      STATUS     PORTS      NAMES
db0e41d6ddf5    mysql   "docker-entrypoint..."   6 days ago   Exited (0) 6 days ago hopeful_bhaskara

In above commands, we used to search images in host machine with name ubuntu and try to show all container process including exit processes as well.

Docker container

Let’s work on one of Docker images and container so that we could understand what we could do with docker containers for an application. For same i have on Debian docker image installed with MySQL that downloaded from link. So here complete MySQL is configured within Debian small image which we could use again and again in docker container and save our changes in docker container in form of same or another image. It’s always better to use official images and change them further according to own requirement and save it as an image So that in future you have your own images with an effective official recommendation and required changes. So we have our image like below.

docker images mysql
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mysql               latest              22be5748ecbe        4 months ago        406MB

Run docker container

Now we could run container of this image, it is a just instance of this image that could be used exactly as MySQL server and could completely different file-system to this image. So we could work on this and can save changes to another image and share it another machine having Docker installed.

#docker run --name MySQL_Server -e MYSQL_ROOT_PASSWORD=passw0rd -d mysql
178a19490576d154f7bc1fe93e15b058c2335619d6805e2de6c72cf7f2dcef78

This way we can run docker container, In this command docker, execute a container from MySQL image tag container name as MySQL_Server with root password variable Docker and run in detach mode.The container has entry-point script which is located in / of container that used to start MySQL server. We can access this container in below way.We would learn about docker run in next article.

#docker ps --format "table{{.ID}}\t{{.Names}}\t{{.Command}}\t{{.Status}}"
CONTAINER ID        NAMES               COMMAND                  STATUS
178a19490576        MySQL_Server        "docker-entrypoint..."   Up 16 minutes

In above command, we used format sub-command so that it would display properly in the browser.

Access Docker container

In Below command we used to execute bash command in container first and then connect MySQL console.

#docker exec -it MySQL_Server bash
root@178a19490576:/# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
mysql        1     0  2 07:04 ?        00:00:00 mysqld
root        73     0  0 07:04 pts/0    00:00:00 bash
root       154    73  0 07:05 pts/0    00:00:00 ps -ef
root@178a19490576:/# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.17 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

mysql> exit
Bye

Now we need to see how we could connect it to any application in such way that we could use this MySQL database in some application for storing its data. For same first we need to export MySQL port outside the container, for same we should first understand Docker network.

Docker Network

When Docker install on any host machine, it configure IPTables in such was that Docker container can access outside world but no one can access it from outside. Below iptables is responsible for this access from container to outside world.

#iptables -t nat  -L POSTROUTING 1
MASQUERADE  all  --  172.17.0.0/16        anywhere

If you ever noticed any container get 172 range of IP by-default, this happened because of Docker default assigned network. Docker has three type of network and by-default any container will have Bridge network as mentioned below output.

#docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
609e7c07d834        bridge              bridge              local
de605e7e8cba        host                host                local
67fdf7cc0ece        none                null                local

#brctl show docker0
bridge name	bridge id		STP enabled	interfaces
docker0		8000.024296f86289	no		vethcef4811

In above output Docker has three network type and in host, we can see bridge contain one interface that container’s interface. So this bridge interface is responsible from docker side to implement those IPTables in such a way that whatever outside world accessible to containers.

#docker network inspect bridge| grep -A 6 Containers
        "Containers": {
            "7c2722addf6c1c7c90af2f14fe17433f8fce9efde81d1f1811beca651985b822": {
                "Name": "MySQL_Server",
                "EndpointID": "1de514c55b8327d6ff1e9c4a4ea925e31655f0a6407e8fc194e0941cedb7a4f8",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""

#ifconfig  docker0
docker0   Link encap:Ethernet  HWaddr 02:42:96:f8:62:89  
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:96ff:fef8:6289/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:692 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:126616 (126.6 KB

root@7c2722addf6c:~# ip route list
default via 172.17.0.1 dev eth0 
172.17.0.0/16 dev eth0  proto kernel  scope link  src 172.17.0.2 
)

In above output, we could see that MySQL_Server container has 172 range IP which could directly contact Host docker0 interface which is also containers default gateway as well and further on host OS iptables helps network to contact outside world. Although it’s complicated and we tried to cover in a small article because the motive of the article is different but i think anyone has knowledge about Linux earlier able to understand it well.

So now we have to see how we could export MySQL port from a container to HOST OS. We could do this in many ways, but in this article, we would follow a simple procedure to do same. We would do expose ports for same. For this, we have to do some changes while creating containers like below.

#netstat -ntlp | grep 3306
#docker run --name MySQL_Server -e MYSQL_ROOT_PASSWORD=passw0rd -d -p 3306:3306 mysql
e7dc4330cee40b7d829a5e2171156b14726c94913a7e584f93f34c4eb9c3d651
#netstat -ntlp | grep 3306
tcp6       0      0 :::3306    :::*    LISTEN    13137/docker-proxy

In this above box we could see earlier there was no 3306 port on listing mode but further, it was on listing mode through docker-proxy. We could connect MySQL like below

#mysql -h 127.0.0.1 -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.17 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

But we have to use -h otherwise it will try to connect local socket that is not present on HOST machine.
we could see port exposed from containers.

#docker port MySQL_Server
3306/tcp -> 0.0.0.0:3306