0% found this document useful (0 votes)
10 views56 pages

14 Dockers

The document discusses the evolution of application hosting from physical servers to virtualization and containers, highlighting the inefficiencies of traditional server setups and the advantages of using containers for application deployment. It introduces Docker as a significant player in container technology, explaining its origins, functionalities, and installation process. The document also covers the basic operations of Docker, including managing images and containers, and demonstrates how to run a container using the Docker Engine.

Uploaded by

Aslam Ansari
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views56 pages

14 Dockers

The document discusses the evolution of application hosting from physical servers to virtualization and containers, highlighting the inefficiencies of traditional server setups and the advantages of using containers for application deployment. It introduces Docker as a significant player in container technology, explaining its origins, functionalities, and installation process. The document also covers the basic operations of Docker, including managing images and containers, and demonstrates how to run a container using the Docker Engine.

Uploaded by

Aslam Ansari
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 56

XIV.

Dockers
1. Applications Era
In today’s world, we are all surrounded by apps and websites. We use our smartphones and
computers to browse around internet and use all the web services through our mobile apps or
browsers. All these millions of web based data is coming somewhere far from some computers
which would be located in some datacenter. We generally call them servers; these servers could be
those physical machines that we see racked up in a datacenter with all those flashing lights and
cables.

If we take some examples like Amazon, Google, Netflix, Goibibo etc, all these businesses are
running on applications or we can say their applications are their business. This makes a very
important point that we cannot separate their business with their application.

Application needs compute resource to run and that comes from the server where they hosted their
application. In olden days when we did not have any virtualization or cloud computing we use to
run them directly on a physical server.

So, if I want to host an application on 10 webservers, I need ten physical servers under load
balancer serving the web traffic.

These servers are very expensive and we need to do lot of maintenance for them.
➢ We need to procure a server. A process where we place an order for the purchase.
➢ There is Capital expenditure or CapEx required.
➢ There is Operational expenditure (OpEx), like cooling, power, admins to maintain that
server farm.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
So, if I want to increase the capacity and add more servers I need to spend money and time on
above mentioned process. This is very common as business starts from very small user base and
then users/consumers traffic increases if business is doing well.

We deploy one application per server because we want our applications to be isolated. For example,
if we need web app, db app and few backend apps.
We may end up having multiple physical system each running a single instance of that app.

So, every time we need a new app to run we buy servers, install OS and setup our app on that.
And most of the time nobody knew the performance requirements of the new application!
This meant IT had to make guesses when choosing the model and size of
servers to buy.

As a result, IT did the only reasonable thing - it bought big fast servers with
lots of resiliency. After all, the last thing anyone wanted - including the
business - was under-powered servers.

Most part of the time these physical server compute resource will be under-utilized as low as 5-10%
of their potential capacity. A tragic waste of company capital and resources.

2. Virtualization Revolution.
VMware gave the world the virtual machine and everything changed after that. Now we could run
multiple applications isolated in separate OS but in the same physical server.
In the virtualization chapter, we discussed the benefits and features of virtualization, The
Hypervisor Architecture.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
3. Problems with Hypervisor Architecture.

Now we know that every VM has its own OS, which is a problem. OS needs fair amount of
resources like CPU, Memory, Storage etc. We also maintain OS licences and nurse them regularly
like patching, upgrades, config changes. We wanted to host an application but collected good
amount of fats over our infra, we are wasting OpEx and CapEx here. Think about shipping a vm
from one place to other place, this sounds a great idea that if we could bundle everything in a vm
image and ship it so the other person doesn’t need to setup vm from scratch can directly run the vm
from image. We did it in Vagrant chapter where we download preinstalled vm and have just run it.

But these images are heavy and bulky as they contain OS with the app. Booting them is a slow
process. So being portable it’s not convenient to ship the vm every time.

Shipping an application bundled with all the dependencies/libraries in an image without OS.
Hmm, sounds like we solved a big problem there. That’s what containers are.

Think about setting up an application in a vm or physical machine. We need OS setup,


dependencies, application deployed and some config changes in the OS. We follow a series of steps
to setup all these like setting up a LAMP stack. If we could bundle all these into one container and
ship it, then admins don’t need to do any setup on the target, all we need to do is pull a container
image and run it.

4. Containers.
If virtual machines are hardware virtualization then containers are OS virtualization. We don’t need
a real OS in the container to install our application. Applications inside the containers are dependent
on Host OS kernel where its running. So, if I have hosted java application like inside the container it
will use all the java libraries and config files from container data, but for compute resource its relied

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
on the Host OS kernel. Containers are like other processes that run in an Operating System but its
isolated, its processes, files, libraries, configurations are contained within the boundaries of the
container. Containers have their own process tree and networking also. Every container will have an
IP address and port on which the application inside container is running. This may sound like a
virtual machine but it’s not, remember VM has its own OS and containers does not.

Containers are very lightweight as it just has the libraries and application. So that means less
compute resource is utilized and that means more free space to run more container's. So, in terms of
resources also we are saving CapEx & OpEx.
Containers is not a modern technology, it was around us in different forms and technologies. But
Docker has brought it to a whole new level when it comes to building, shipping and managing
containers.

5. Dockers
Docker, Inc. started its life as a platform as a service (PaaS) provider called dotCloud. Behind the
scenes, the dotCloud platform leveraged Linux contain-ers. To help them create and manage these

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
containers they built an internal tool that they nick-named “Docker”. And that’s how Docker was
born!
In 2013 the dotCloud PaaS business was struggling and the company needed a new lease of life. To
help with this they hired Ben Golub as new CEO, rebranded the company as “Docker, Inc.”, got rid
of the dotCloud PaaS platform, and started a new journey with a mission to bring to Docker and
containers to the world.
Docker relies on Linux kernel features, such as namespaces and cgroups, to ensure resource
isolation and to package an application along with its dependencies. This packaging of the
dependencies enables an application to run as expected across different Linux operating systems.
It’s this portability that’s piqued the interest of developers and systems administrators alike.
But when somebody says “Docker” they can be referring to any of at least three things:

Docker, Inc. the company


Docker the container runtime and orchestration technology
3. Docker the open source project

When most of the people talk about Docker they generally refer to the Docker Engine.
Docker engine runs and orchestrate containers. As of now we can think docker engine like a
hypervisor. The same way as hypervisor technology that runs virtual machines, the Docker Engine
is the core container runtime that runs containers.

There are so many Docker technologies that gets integrated with the docker engine to automate,
orchestrate or manage docker containers.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
6. Installing Docker.
Docker can be installed on Windows, Mac and Linux OS.
We will install docker on Ubuntu 16.04 server in this tutorial.
Docker can be installed directly from Ubuntu repositories but that may not be the latest version of
Docker engine. To install the latest and greatest version, we will install it from official Docker
repository.

Uninstall old versions


Older versions of Docker were called docker or docker-engine. If these are installed,
uninstall them:
$ sudo apt-get remove docker docker-engine

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
It’s OK if apt-get reports that none of these packages are installed.

Add GPG key for Docker repository.


curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

Add the Docker repository


sudo add-apt-repository "deb [arch=amd64]
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

Update the package


sudo apt-get update

Install Docker:
sudo apt-get install docker-ce -y

Docker should now be installed, the daemon started, and the process enabled to start on boot. Check
that it's running:
sudo systemctl status docker

Docker commands can be executed by root user or by providing sudo.


We can run docker command with normal user as well, to do it we need to add the user into the
docker group.

sudo usermod -aG docker <username>

You need to logout and login to reflect the changes.

Run Docker command to check if it’s working.

docker --version

When you install docker engine you get two components.


➢ Docker Client
➢ Docker Engine

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
7. Docker Engine’s Big Picture

Let’s quickly feel and taste the docker engine before we dive deep into it.

Broadly there are two areas where we operate in docker engines.


➢ Docker Images

➢ Docker containers

Images
As of now you can think images as vagrant boxes. It’s very much different from the vm images but
it will feel as same initially. Vagrant boxes are stopped state of a VM and Images and stopped state
of containers.

Run docker images command.

$ docker images

This command will list the downloaded images on your machine, so you won’t see anything now in
the output. We need to download some images, in docker world we call it Pulling an image.

So where does it pull the image from? Again, same analogy as vagrant boxes. We download the
vagrant boxes from vagrant cloud, docker images are downloaded from Docker Registries, the
most famous docker registry is DockerHub. There are other registries as well, from google, redhat
etc.

$ docker pull ubuntu:latest

latest: Pulling from library/ubuntu

bd97b43c27e3: Pull complete

6960dc1aba18: Pull complete

2b61829b0db5: Pull complete

1f88dc826b14: Pull complete

73b3859b1e43: Pull complete

Digest: sha256:ea1d854d38be82f54d39efe2c67000bed1b03348bcc2f3dc094f260855dff368

Status: Downloaded newer image for ubuntu:latest

Run the docker images command again to see the ubuntu:latest image you just pulled.

$ docker images

REPOSITORY TAG IMAGE ID CREATED SIZE

ubuntu latest 7b9b13f7b9c0 2 weeks ago 118MB

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
We’ll get into the details of where the image is stored and what’s inside of it in the next chapter. For
now, it’s enough to understand that it contains enough of an operating system (OS), as well as all
the code to run whatever application it’s designed for. The ubuntu image that we’ve pulled has a
stripped-down version of the Ubuntu Linux OS including a few of the common Ubuntu utilities.

Containers

Now that we have an image pulled locally on our Docker host, we can use the docker run command
to launch a container from it.

imran@DevOps:~$ docker run -it ubuntu:latest /bin/bash

root@b8765d3a67a9:/#

Look closely at the output form the command above. You should notice that your shell prompt has
changed. This is because your shell is now attached to the shell of the new container - you are
literally inside of the new container!

Let’s examine that docker run command.

➢ docker run tells the Docker daemon to start a new container.

➢ The -it flags tell the daemon to make the container interactive and to attach our current shell
to the shell of the container.

➢ Next, the command tells Docker that we want the container to be based on the ubuntu:latest
image.

➢ We tell it to run the /bin/bash process inside the container.

Run the following ps command from inside of the container to list all running processes.
root@b8765d3a67a9:/# ps -elf

F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD

4 S root 1 0 0 80 0 - 4560 wait 19:46 ? 00:00:00 /bin/bash

0 R root 10 1 0 80 0 - 8606 - 19:50 ? 00:00:00 ps -elf

As you can see from the output of the ps command, there are only two processes running inside of
the container:

➢ PID 1. This is the/bin/bash process that we told the container to run with the docker run command.

➢ PID 10. This is the ps ­elf process that we ran to list the running processes.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
The presence of the ps -elf process in the output above could be a bit misleading as it is a short-
lived process that dies as soon as the ps command exits. This means that the only long-running
process inside of the container is the /bin/bash process.

Press Ctrl-PQ to exit the container. This will land you back in the shell of your Docker host. You
can verify this by looking at your shell prompt.

In a previous step you pressed Ctrl-PQ to exit your shell from the container. Doing this from inside
of a container will exit you form the container without killing it. You can see all the running
containers on your system using the docker ps command.

imran@DevOps:~$ docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS


PORTS NAMES

b8765d3a67a9 ubuntu:latest "/bin/bash" 6 minutes ago Up 6 minutes


inspiring_heyrovsky

The output above shows a single running container. This is the container that you created earlier.
The presence of your container in this output

proves that it’s still running. You can also see that it was created 6 minutes ago and has been
running for 6 minutes.

Attaching to running containers

You can attach your shell to running containers with the docker exec command. As the container
from the previous steps are still running let’s connect back to it.

Note: The example below references a container called “inspiring_heyrovsky”. The name of your
container will be different, so remember to substitute “inspiring_heyrovsky” with the name or ID of
the container running on your Docker host.

imran@DevOps:~$ docker exec -it inspiring_heyrovsky /bin/bash

root@b8765d3a67a9:/#

Notice that your shell prompt has changed again. You are back inside the container.

The format of the docker exec command is:


docker exec -options <container-name or container-id> <command>.

In our example, we used the -it options to attach our shell to the container’s shell. We referenced the
container by name and told it to run the bash shell.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
Exit the container again by pressing Ctrl-PQ.

Your shell prompt should be back to your Docker host.

Run the docker ps command again to verify that your container is still running.

imran@DevOps:~$ docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS


PORTS NAMES

b8765d3a67a9 ubuntu:latest "/bin/bash" 13 minutes ago Up 13 minutes


inspiring_heyrovsky

Stop the container and kill it using the docker stop and docker rm commands.

imran@DevOps:~$ docker stop inspiring_heyrovsky

inspiring_heyrovsky

imran@DevOps:~$ docker rm inspiring_heyrovsky

inspiring_heyrovsky

Verify that the container was successfully deleted by running another docker ps command.

imran@DevOps:~$ docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS


PORTS NAMES

imran@DevOps:~$

Now you would have got the taste of docker images and containers. We pulled an image, executed a
container, stopped and removed it. In next section, we will dig more in detail of images and then
containers.

8. Images
We have seen very basic stuff of docker images, now we will do a deep dive into docker images.
Images are built and distributed like software. As we have seen in Continuous Integration chapter
that there should be a process of Build & Release a software, we must do the same if we are
releasing Images.
We have mentioned earlier Images are stopped state of container so you can stop a container and
create a new image from it.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
We
see
fro
m
abo
ve
figu
re that we pull an image, run a container, customize it as per our requiretment, commit the container
into an image and then ship it.
However, once you’ve started a container form an image, the two constructs become dependent on
each other and you cannot delete the image until the last container using it has been stopped and
destroyed. Attempting to delete an image without stopping and destroying all containers using it
will result in errors.

Images that we are shipping should be light weight and should only contain the files and libraries
that required to run the application inside it. For example, if we are shipping a java application, it
should contain only java libraries, application server like tomcat and files to run our app and not
anything extra.

Pulling Images.

imran@DevOps:~$ docker pull node:latest

latest: Pulling from library/node

ef0380f84d05: Pull complete

24c170465c65: Pull complete

4f38f9d5c3c0: Pull complete

4125326b53d8: Pull complete

a1468c06f443: Pull complete

cb113e1791ca: Pull complete

519ce9303f95: Pull complete

f15f31d0549a: Pull complete

Digest: sha256:1d496e5c8e692dfabeb1cc8a18f01e2b501111f32c3d08e94e5402daeceb94e6

Status: Downloaded newer image for node:latest

$ docker images

REPOSITORY TAG IMAGE ID CREATED SIZE

node latest f3068bc71556 27 hours ago 667MB

ubuntu latest 7b9b13f7b9c0 2 weeks ago 118MB

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
As you can see now we have two images downloaded on our docker engine.

Image registries

Docker images are stored in image registries. The most common image registry is Docker Hub.
Other registries exist including 3rd party registries and secure on-premises registries, but Docker
Hub is the default, and it’s the one we’ll use in this tutorial.

https://hub.docker.com/

Image registries contain multiple image repositories. Image repositories contain images. That might
be a bit confusing, so Figure 5.2 shows a picture of an image registry containing 3 repositories, and
each repository contains a few images.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
Docker hub contains Official and unofficial repositories.
Official repositories are from Docker, Inc. These are safe and secure images with latest up to date
software.

Unofficial repositories are uploaded by anyone and are not verified by Docker, Inc.

The list below contains a few of the official repositories and shows their URLs that exist at the top
level of the Docker Hub namespace:
• nginx - https://hub.docker.com/_/nginx/
• busybox - https://hub.docker.com/_/busybox/
• redis - https://hub.docker.com/_/redis/
• mongo - https://hub.docker.com/_/mongo/

Our personal images live in the unofficial repositories. Below are some examples of images in my
repositories:
visualpath/myjsonsinatra - https://hub.docker.com/r/visualpath/myjsonsinatra/
visualpath/devops-docker-ci - https://hub.docker.com/r/visualpath/devops-docker-ci/

Image Tags.
While pulling a image we give the imagename:TAG and docker will reach by default to dockerhub
registry and find the image with the TAG we specified.

docker pull nginx:latest

Tag generally refers to the version of the image from the repository.
If we are looking for some other version like 1.12.0 then we can use below command.

docker pull nginx:1.12.0

If we do not specify any tag then the default tag is latest. Latest tag does not mean that the images is
latest in version, it’s just the name of the tag and that’s all.
docker pull nginx

Above command will download the nginx image with latest tag.

Images and layers

All Docker images are made up of one or more read-only layers as shown below.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
There are a few ways to see and inspect the layers that make up an image,

and we’ve already seen one of them. Let’s take a second look at the output of the docker
pull node:latest command from earlier:

$ docker pull node

Using default tag: latest

latest: Pulling from library/node

ef0380f84d05: Pull complete

24c170465c65: Pull complete

4f38f9d5c3c0: Pull complete

4125326b53d8: Pull complete

a1468c06f443: Pull complete

cb113e1791ca: Pull complete

519ce9303f95: Pull complete

f15f31d0549a: Pull complete

Digest: sha256:1d496e5c8e692dfabeb1cc8a18f01e2b501111f32c3d08e94e5402daeceb94e6

Each line in the output above that ends with “Pull complete” represents a layer in the image that
was pulled. As we can see, this image has 5 layers.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
Each layer is only a set of differences from the layer before it. The layers are stacked on top of each
other. When you create a new container, you add a new writable layer on top of the underlying
layers. This layer is often called the “container layer”. All changes made to the running container,
such as writing new files, modifying existing files, and deleting files, are written to this thin
writable container layer. The diagram below shows a container based on the Ubuntu 15.04 image.

Container and layers


The major difference between a container and an image is the top writable layer. All writes to the
container that add new or modify existing data are stored in this writable layer. When the container
is deleted, the writable layer is also deleted. The underlying image remains unchanged.
Because each container has its own writable container layer, and all changes are stored in this
container layer, multiple containers can share access to the same underlying image and yet have
their own data state. The diagram below shows multiple containers sharing the same Ubuntu 15.04
image.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
Docker uses storage drivers to manage the contents of the image layers and the writable container
layer. Each storage driver handles the implementation differently, but all drivers use stackable
image layers and the copy-on-write (CoW) strategy.

Another way to see the layers that make up an image is to inspect the
image with the docker inspect command. The example below inspects the same ubuntu:latest
image.

$ docker inspect node

"Id": "sha256:f3068bc71556e181c774ee7dadc4d3ebbf5643e95680a202779f08146332547d",

"RepoTags": [

"node:latest"

],

"RepoDigests": [

"node@sha256:1d496e5c8e692dfabeb1cc8a18f01e2b501111f32c3d08e94e5402daeceb94e6"

],

"Parent": "",

"Comment": "",

"Created": "2017-06-15T17:26:33.424702587Z",

"Container": "8c6ffc2b7a445e6f2ade22c6be3a430c772e0ab61bf0ee4fff69b36a24e9123e",

"ContainerConfig": {

"Hostname": "5c84359661e5",

"Domainname": "",

"User": "",

"AttachStdin": false,

"AttachStdout": false,

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
"AttachStderr": false,

"Tty": false,

"OpenStdin": false,

"StdinOnce": false,

"Env": [

"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",

"NPM_CONFIG_LOGLEVEL=info",

"NODE_VERSION=8.1.2",

"YARN_VERSION=0.24.6"

],

"Cmd": [

"/bin/sh",

"-c",

"#(nop) ",

"CMD [\"node\"]"

],

"ArgsEscaped": true,

"Image": "sha256:3864d82628abf07bbdebe3d1d529aa90eef89f8dc99d06dea2a35329879c81a7",

"Volumes": null,

"WorkingDir": "",

"Entrypoint": null,

"OnBuild": [],

"Labels": {}

},

"DockerVersion": "17.03.1-ce",

"Author": "",

"Config": {

"Hostname": "5c84359661e5",

"Domainname": "",

"User": "",

"AttachStdin": false,

"AttachStdout": false,

"AttachStderr": false,

"Tty": false,

"OpenStdin": false,

"StdinOnce": false,

"Env": [

"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",

"NPM_CONFIG_LOGLEVEL=info",

"NODE_VERSION=8.1.2",

"YARN_VERSION=0.24.6"

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
],

"Cmd": [

"node"

],

"ArgsEscaped": true,

"Image": "sha256:3864d82628abf07bbdebe3d1d529aa90eef89f8dc99d06dea2a35329879c81a7",

"Volumes": null,

"WorkingDir": "",

"Entrypoint": null,

"OnBuild": [],

"Labels": {}

},

"Architecture": "amd64",

"Os": "linux",

"Size": 666628404,

"VirtualSize": 666628404,

"GraphDriver": {

"Data": null,

"Name": "aufs"

},

"RootFS": {

"Type": "layers",

"Layers": [

"sha256:007ab444b234be691d8dafd51839b7713324a261b16e2487bf4a3f989ded912d",

"sha256:4902b007e6a712835de8e09c385c0f061638323c3cacc13f7190676f05dad9d7",

"sha256:bb07d0c1008de4fd468f865764e6f1129ba53f4bfe6ab14dd5eb3ab256947ab0",

"sha256:ecf5c2e2468e7fe6600193972ffc659214050d8829f44e5194a22997de13aab4",

"sha256:7b3b4fef39c1df95f7a015716bc980dad38fff92ebba6de82d5add10b1258523",

"sha256:677f02386f077da16bfbe00af5305928545c11c40dccf70f93fa332f617c1fba",

"sha256:99c62c5bb4f21ab5b288339ce1a29e33cb3a82670ec1a9254730b6925d7da7dc",

"sha256:0dd4309d61fe600b230931ce669a93ee0baf9b2c18f574749c3af1e3eed44b83"

Deleting Images

When you no longer need an image, you can delete it form your Docker host with the docker rmi
command. rmi is short for remove image.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
Delete the node image pulled in the previous step with the docker rmi command. The example
below addresses the image by its ID.

$ docker rmi f3068bc71556

9. Containers
Container is the runtime instance of an image like we start a vm from vagrant box. We can start
multiple containers from one single image.
We create container from an image by giving docker run command. Containers run until the
processes running inside them exists. There should be minimum one process running inside the
container with PID 1. If this process dies the containers also dies.

imran@DevOps:~$ docker run -it ubuntu:latest /bin/bash

root@ae141c80e436:/# ps -ef

UID PID PPID C STIME TTY TIME CMD

root 1 0 2 21:44 ? 00:00:00 /bin/bash

root 11 1 0 21:44 ? 00:00:00 ps -ef

In above container /bin/bash has the PID 1, this process will get killed if we hit exit command.
root@ae141c80e436:/# exit

exit

imran@DevOps:~$ docker ps

CONTAINER ID IMAGE COMMAND CREATED


STATUS PORTS NAMES

As exit will logout and kill the current shell and that’s our PID 1 our container also got killed with
it.

docker ps -a will show all the containers running or exited.


imran@DevOps:~$ docker ps -a

CONTAINER ID IMAGE COMMAND CREATED STATUS


PORTS NAMES

ae141c80e436 ubuntu:latest "/bin/bash" 12 minutes ago Exited (0) 10


minutes ago zen_bell

159b1586b69b ubuntu:latest "/bin/bash" 12 minutes ago Exited (0) 12


minutes ago hungry_noether

We can start a exited container by giving docker start <containerid>


imran@DevOps:~$ docker start ae141c80e436

ae141c80e436

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
imran@DevOps:~$ docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS


PORTS NAMES

ae141c80e436 ubuntu:latest "/bin/bash" 14 minutes ago Up 3 seconds


zen_bell

docker stop will stop a running container.


imran@DevOps:~$ docker stop ae141c80e436

ae141c80e436

docker rm will remove the container with its data.


imran@DevOps:~$ docker rm ae141c80e436

ae141c80e436

Running a webservice in a container.


imran@DevOps:~$ docker run -d --name newwebserver -p 8070:80 visualpath/devops-
docker-ci

c695f224adf6a91f971018c6934b255e5cb86d6d8f6a4445d24fa7d7f1f70967

We started the above container in backgroud by option -d


we also have given name to our container by --name option
Above image is an apache webservice which is running on port 80 but can be accessed by
forwarded port from host. Host Port 8070 is mapped to containers port 80. That means if we access
host machines IP on port 8070 we will get service running on port 80 from the containers.
Containers are not directly accessed by their IP’s because container Ip’s are not permanent. We will
discuss that in detail in networking section. We access service running in container from host port
which are redirected to containers port this is called a port forwarding.
-p 8070:80 means host port 8070 is mapped to containers port 80.
Verify the container webservice by accessing it from browser on http://hostip:8070

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
Check nginx, apache and Jenkins registries from dockerhub and run them to understand more about
it.

$ docker run -p 8080:8080 -p 50000:50000 -v /your/home:/var/jenkins_home Jenkins

Here we are mapping two ports 8080 and 50000, host and container ports are same which is ok if
your host ports are not busy.
Containers data is not persistent that means if we delete the container its data is also lost, which is
obvious. But if we want to keep that data safe on host machine, we can use -v flag which is for
volumes. Left hand side is host machine directory path and right-hand side is containers directory
path which you want to save on host machine. It’s similar to our vagrant sync directories.
Now even if we delete the container its data in /var/jenkins_home will be safe on the host machine
in /your/home directory.

Inspecting Containers
In the previous example you might have noticed that we didn’t specify a command for the container
when we issued the docker run. Yet the container ran a simple web service. How did this happen?
When building a Docker image, it’s possible to embed a default command or process you want
containers using the image to run. If we run a docker inspect command against the image we used
to run our container, we’ll be able to see the command/process that the container will run when it
starts.

imran@DevOps:~$ docker inspect c695f224adf6a91f971018c6934b255e5cb86d6d8f6a4445d24fa7d7f1f70967

"Id": "c695f224adf6a91f971018c6934b255e5cb86d6d8f6a4445d24fa7d7f1f70967",

"Created": "2017-06-16T22:13:41.841190294Z",

"Path": "/bin/sh",

"Args": [

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
"-c",

"/usr/sbin/apache2ctl -D FOREGROUND"

],

"State": {

"Status": "running",

"Running": true,

"Paused": false,

"Restarting": false,

"OOMKilled": false,

"Dead": false,

"Pid": 17026,

"ExitCode": 0,

"Error": "",

"StartedAt": "2017-06-16T22:13:42.656496753Z",

"FinishedAt": "0001-01-01T00:00:00Z"

10. Building & Shipping Images


Docker can build images automatically by reading the instructions from a Dockerfile, a text file that
contains all the commands, in order, needed to build a given image. Dockerfiles adhere to a specific
format and use a specific set of instructions.

Dockerfile will define what goes on in the environment inside your container. Access to resources like
networking interfaces and disk drives is virtualized inside this environment, which is isolated from the
rest of your system, so you have to map ports to the outside world, and be specific about what files you
want to “copy in” to that environment. However, after doing that, you can expect that the build of your
app defined in thisDockerfile will behave exactly the same wherever it runs.

Dockerfile
Create an empty directory and put this file in it, with the name Dockerfile. Take note of the comments
that explain each statement.
# Use an official Python runtime as a base image

FROM python:2.7-slim

# Set the working directory to /app

WORKDIR /app

# Copy the current directory contents into the container at /app

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
ADD . /app

# Install any needed packages specified in requirements.txt

RUN pip install -r requirements.txt

# Make port 80 available to the world outside this container

EXPOSE 80

# Define environment variable

ENV NAME World

# Run app.py when the container launches

CMD ["python", "app.py"]

This Dockerfile refers to a couple of things we haven’t created yet, namely app.py and
requirements.txt. Let’s get those in place next.
The app itself

Grab these two files and place them in the same folder as Dockerfile. This completes our app, which as
you can see is quite simple. When the above Dockerfile is built into an image, app.py and
requirements.txtwill be present because of that Dockerfile’s ADD command, and the output from app.py will
be accessible over HTTP thanks to the EXPOSE command.

requirements.txt
Flask

Redis

app.py
from flask import Flask

from redis import Redis, RedisError

import os

import socket

# Connect to Redis

redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
@app.route("/")

def hello():

try:

visits = redis.incr("counter")

except RedisError:

visits = "<i>cannot connect to Redis, counter disabled</i>"

html = "<h3>Hello {name}!</h3>" \

"<b>Hostname:</b> {hostname}<br/>" \

"<b>Visits:</b> {visits}"

return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":

app.run(host='0.0.0.0', port=80)

Now we see that pip install -r requirements.txt installs the Flask and Redis libraries for Python, and the app
prints the environment variable NAME, as well as the output of a call to socket.gethostname(). Finally,
because Redis isn’t running (as we’ve only installed the Python library, and not Redis itself), we should
expect that the attempt to use it here will fail and produce the error message.

Note: Accessing the name of the host when inside a container retrieves the container ID,
which is like the process ID for a running executable.

Build the app

That’s it! You don’t need Python or anything in requirements.txt on your system, nor will building or
running this image install them on your system. It doesn’t seem like you’ve really set up an environment
with Python and Flask, but you have.

Here’s what ls should show:

$ ls

Dockerfile app.py requirements.txt

Now run the build command. This creates a Docker image, which we’re going to tag using -t so it has a
friendly name.

docker build -t friendlyhello .

Where is your built image? It’s in your machine’s local Docker image registry:

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
$ docker images

REPOSITORY TAG IMAGE ID

friendlyhello latest 326387cea398

Run the app

Run the app, mapping your machine’s port 4000 to the container’s EXPOSEd port 80 using -p:

docker run -p 4000:80 friendlyhello

You should see a notice that Python is serving your app at http://0.0.0.0:80. But that message is coming
from inside the container, which doesn’t know you mapped port 80 of that container to 4000, making
the correct URL http://localhost:4000.

Go to that URL in a web browser to see the display content served up on a web page, including
“Hello World” text, the container ID, and the Redis error message.

You can also use the curl command in a shell to view the same content.

$ curl http://localhost:4000

<h3>Hello World!</h3><b>Hostname:</b> 8fc990912a14<br/><b>Visits:</b> <i>cannot connect to Redis, counter


disabled</i>

Note: This port remapping of 4000:80 is to demonstrate the difference between what you
EXPOSEwithin the Dockerfile, and what you publish using docker run -p. In later steps, we’ll
just map port 80 on the host to port 80 in the container and use http://localhost.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
Hit CTRL+C in your terminal to quit.

Now let’s run the app in the background, in detached mode:

docker run -d -p 4000:80 friendlyhello

You get the long container ID for your app and then are kicked back to your terminal. Your container is
running in the background. You can also see the abbreviated container ID with docker ps (and both work
interchangeably when running commands):

$ docker ps

CONTAINER ID IMAGE COMMAND CREATED

1fa4ab2cf395 friendlyhello "python app.py" 28 seconds ago

You’ll see that CONTAINER ID matches what’s on http://localhost:4000.

Now use docker stop to end the process, using the CONTAINER ID, like so:

docker stop 1fa4ab2cf395

Share your image

To demonstrate the portability of what we just created, let’s upload our built image and run it
somewhere else. After all, you’ll need to learn how to push to registries when you want to deploy
containers to production.

A registry is a collection of repositories, and a repository is a collection of images—sort of like a


GitHub repository, except the code is already built. An account on a registry can create many
repositories. The dockerCLI uses Docker’s public registry by default.
Note: We’ll be using Docker’s public registry here just because it’s free and pre-configured,
but there are many public ones to choose from, and you can even set up your own private
registry using Docker Trusted Registry.

Log in with your Docker ID


If you don’t have a Docker account, sign up for one at cloud.docker.com. Make note of your
username.
Log in to the Docker public registry on your local machine.
docker login

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
Tag the image
The notation for associating a local image with a repository on a registry is username/repository:tag. The
tag is optional, but recommended, since it is the mechanism that registries use to give Docker images a
version. Give the repository and tag meaningful names for the context, such as get-started:part1. This will
put the image in the get-started repository and tag it as part1.

Now, put it all together to tag the image. Run docker tag image with your username, repository, and tag
names so that the image will upload to your desired destination. The syntax of the command is:
docker tag image username/repository:tag

For example:

docker tag friendlyhello john/get-started:part1

Run docker images to see your newly tagged image. (You can also use docker image ls.)

$ docker images

REPOSITORY TAG IMAGE ID CREATED SIZE

friendlyhello latest d9e555c53008 3 minutes ago 195MB

john/get-started part1 d9e555c53008 3 minutes ago 195MB

python 2.7-slim 1c7128a655f6 5 days ago 183MB

...

Publish the image


Upload your tagged image to the repository:

docker push username/repository:tag

Once complete, the results of this upload are publicly available. If you log in to Docker Hub, you will
see the new image there, with its pull command.

Pull and run the image from the remote repository


From now on, you can use docker run and run your app on any machine with this command:

docker run -p 4000:80 username/repository:tag

If the image isn’t available locally on the machine, Docker will pull it from the repository.

$ docker run -p 4000:80 john/get-started:part1

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
Unable to find image 'john/get-started:part1' locally

part1: Pulling from orangesnap/get-started

10a267c67f42: Already exists

f68a39a6a5e4: Already exists

9beaffc0cf19: Already exists

3c1fe835fb6b: Already exists

4c9f1fa8fcb8: Already exists

ee7d8f576a14: Already exists

fbccdcced46e: Already exists

Digest: sha256:0601c866aab2adcc6498200efd0f754037e909e5fd42069adeff72d1e2439068

Status: Downloaded newer image for john/get-started:part1

* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)

Note: If you don’t specify the :tag portion of these commands, the tag of :latest will be
assumed, both when you build and when you run images. Docker will use the last version of
the image that ran without a tag specified (not necessarily the most recent image).

No matter where docker run executes, it pulls your image, along with Python and all the dependencies
from requirements.txt, and runs your code. It all travels together in a neat little package, and the host
machine doesn’t have to install anything but Docker to run it.

Dockerfile Instructions
We have seen in previous section that Dockerfile is used to build docker images. It contains the list
of instructions that docker reads to setup an Image. There are around a dozen Instruction that we
can use in our Dockerfile.

1.ADD
2.CMD
3.ENTRYPOINT
4.ENV
5.EXPOSE
6.FROM
7.MAINTAINER
8.RUN
9.USER
10.VOLUME
11.WORKDIR
12.ONBUILD

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
FROM

This instruction is used to set the base image for subsequent instructions. It is mandatory to set this
in the first line of a Dockerfile. You can use it any number of times though.
Example:
FROM ubuntu:latest

MAINTAINER
This is a non-executable instruction used to indicate the author of the Dockerfile.
Example:
MAINTAINER <name>

RUN
This instruction lets you execute a command on top of an existing layer and create a new layer with
the results of command execution.
For example, if there is a pre-condition to install PHP before running an application, you can run
appropriate commands to install PHP on top of base image (say Ubuntu) like this:
FROM ubuntu

RUN apt-get update update apt-get install php5

CMD
The major difference between CMD and RUN is that CMD doesn’t execute anything during the build
time. It just specifies the intended command for the image. Whereas RUN executes the command
during build time.
Note: there can be only one CMD instruction in a Dockerfile, if you add more, only the last one takes
effect.
Example:
CMD "echo" "Hello World!"

EXPOSE
While running your service in the container you may want your container to listen on specified
ports. The EXPOSE instruction helps you do this.
Example:
EXPOSE 6456

ENV
This instruction can be used to set the environment variables in the container.
Example:
ENV var_home="/var/etc"

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
COPY
This instruction is used to copy files and directories from a specified source to a destination (in the
file system of the container).
Example:
COPY preconditions.txt /usr/temp

ADD
This instruction is similar to the COPY instruction with few added features like remote URL support
in the source field and local-only tar extraction. But if you don’t need an extra feature, it is
suggested to use COPY as it is more readable.
Example:
ADD http://www.site.com/downloads/sample.tar.xz /usr/src

ENTRYPOINT
You can use this instruction to set the primary command for the image.
For example, if you have installed only one application in your image and want it to run whenever
the image is executed, ENTRYPOINT is the instruction for you.
Note: arguments are optional, and you can pass them during the runtime with something like
docker run <image-name>.
Also, all the elements specified using CMD will be overridden, except the arguments. They will be
passed to the command specified in ENTRYPOINT.
Example:
CMD "Hello World!"

ENTRYPOINT echo

VOLUME
You can use the VOLUME instruction to enable access to a location on the host system from a
container. Just pass the path of the location to be accessed.
Example:
VOLUME /data

USER
This is used to set the UID (or username) to use when running the image.
Example:
USER daemon

WORKDIR
This is used to set the currently active directory for other instructions such as RUN, CMD,
ENTRYPOINT, COPY and ADD.
Note that if relative path is provided, the next WORKDIR instruction will take it as relative to the
path of previous WORKDIR instruction.
Example:

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
WORKDIR /user

WORKDIR home

RUN pwd

This will output the path as /user/home.

ONBUILD
This instruction adds a trigger instruction to be executed when the image is used as the base for
some other image. It behaves as if a RUN instruction is inserted immediately after the FROM
instruction of the downstream Dockerfile. This is typically helpful in cases where you need a static
base image with a dynamic config value that changes whenever a new image must be built (on top
of the base image).
Example:
ONBUILD RUN rm -rf /usr/temp

Dockerhub has Dockerfile for every official Image that’s hosted there.

Above screenshot is from nginx official repository from Dockerhub. If you see there are links to
Dockerfile for every version of the image. The links points to Dockerfile hosted in github.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
These Dockerfiles are the best place to learn the Dockerfile as its verified from Docker Inc.
One of the best practice is that we combine multiple commands in RUN instruction by using &&
Every RUN instruction creates layer on the images, so if you have ten RUN instruction that creates
ten extra layers in your image. To avoid this, we can right all the commands in single RUN
instruction by combining all the commands with && as shown in above screenshot.

A sample mongodb Dockerfile.

############################################################

# Dockerfile to build MongoDB container images

# Based on Ubuntu

############################################################

# Set the base image to Ubuntu

FROM ubuntu

# File Author / Maintainer

MAINTAINER Example McAuthor

# Update the repository sources list

RUN apt-get update

################## BEGIN INSTALLATION ######################

# Install MongoDB Following the Instructions at MongoDB Docs

# Ref: http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/

# Add the package verification key

RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10

# Add MongoDB to the repository sources list

RUN echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist


10gen' | tee /etc/apt/sources.list.d/mongodb.list

# Update the repository sources list once more

RUN apt-get update

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
# Install MongoDB package (.deb)

RUN apt-get install -y mongodb-10gen

# Create the default data directory

RUN mkdir -p /data/db

##################### INSTALLATION END #####################

# Expose the default port

EXPOSE 27017

# Default port to execute the entrypoint (MongoDB)

CMD ["--port 27017"]

# Set default container command

ENTRYPOINT usr/bin/mongod

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
11. Container Networking Basics

A simple, static web server

Run the Docker Hub image nginx, which contains a basic web server:

imran@DevOps:~$ docker run -d -P nginx

b53c99839ccf662b17ff96424352701cc494b788e4d97525d930406b0cfdb237

Docker will download the image from the Docker Hub.

-d tells Docker to run the image in the background.

-P tells Docker to make this service reachable from other computers.


(-P is the short version of --publish-all.)

But, how do we connect to our web server now?

Finding our web server port

We will use docker ps:

imran@DevOps:~$ docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS


PORTS NAMES

b53c99839ccf nginx "nginx -g 'daemon ..." About a minute ago Up About a


minute 0.0.0.0:32769->80/tcp distracted_bassi

The web server is running on ports 80 and 443 inside the container.Those ports are mapped to
ports 32769 and 32768 on our Docker host.We will explain the whys and hows of this port
mapping.
But first, let's make sure that everything works properly.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
Connecting to our web server (GUI)
Point your browser to the IP address of your Docker host, on the port shown by
docker ps for container port 80.

Connecting to our web server (CLI)


You can also use curl directly from the Docker host.

Make sure to use the right port number if it is different from the example below:

$ curl localhost:32769

<!DOCTYPE html> <html>

<head>

<title>Welcome to nginx!</title>

Why are we mapping ports?


We are out of IPv4 addresses. Containers cannot have public IPv4 addresses. They have private
addresses. Services have to be exposed port by port. Ports have to be mapped to avoid conflicts.

Finding the web server port in a script

Parsing the output of docker ps would be painful.There is a command to help us:


$ docker port <containerID>
80 32769

Manual allocation of port numbers

If you want to set port numbers yourself, no problem:

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
$ docker run -d -p 80:80 nginx

$ docker run -d -p 8000:80 nginx

$ docker run -d -p 8080:80 -p 8888:80 nginx

We are running two NGINX web servers. The first one is exposed on port 80.The second one is
exposed on port 8000.The third one is exposed on ports 8080 and 8888.Note: the convention is
port-on-host: port-on-container.

Plumbing containers into your infrastructure

There are many ways to integrate containers in your network. Start the container, letting Docker
allocate a public port for it. Then retrieve that port number and feed it to your configuration.

Pick a fixed port number in advance, when you generate your configuration. Then start your
container by setting the port numbers manually.

Use a network plugin, connecting your containers with e.g. VLANs, tunnels...
Enable Swarm Mode to deploy across a cluster.

The container will then be reachable through any node of the cluster.

Finding the container's IP address

We can use the docker inspect command to find the IP address of the container.

$ docker inspect --format '{{

.NetworkSettings.IPAddress }}' <yourContainerID> 172.17.0.3

docker inspect is an advanced command, that can retrieve a ton of information about our
containers. Here, we provide it with a format string to extract exactly the private IP address of the
container.

Pinging our container

We can test connectivity to the container using the IP address we've just discovered.
Let's see this now by using the ping tool.

$ ping <ipAddress>

64 bytes from <ipAddress>: icmp_req=1 ttl=64 time=0.085 ms 64 bytes from

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
The different network drivers

A container can use one of the following drivers:

bridge (default)

none

host

container

The driver is selected with docker run --net ....

The default bridge

By default, the container gets a virtual eth0 interface. (In addition to its own private lo loopback
interface.)

That interface is provided by a veth pair. It is connected to the Docker bridge.


(Named docker0 by default; configurable with --bridge.)

Addresses are allocated on a private, internal subnet.


(Docker uses 172.17.0.0/16 by default; configurable with –bip.)

Outbound traffic goes through an iptables MASQUERADE rule. Inbound traffic goes through an
iptables DNAT rule. The container can have its own routes, iptables rules, etc.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
12. The Container Network Model

The Container Network Model

The CNM was introduced in Engine 1.9.0 (November 2015).

The CNM adds the notion of a network, and a new top-level command to manipulate and see
those networks: docker network.

What's in a network?

• Conceptually, a network is a virtual switch.


• It can be local (to a single Engine) or global (across multiple hosts).
• A network has an IP subnet associated to it.
• A network is managed by a driver.
• A network can have a custom IPAM (IP allocator).
• Containers with explicit names are discoverable via DNS.
• All the drivers that we have seen before are available.
• A new multi-host driver, overlay, is available out of the box.
• More drivers can be provided by plugins (OVS, VLAN...)

Creating a network

Let's create a network called dev.

$ docker network create dev

27c06defdb9d99002e670935d8fbcd24ef7f24eb3fd1c22b18f383005722a3c4

The network is now visible with the network ls command:

$ docker network ls

NETWORK ID NAME DRIVER SCOPE

d7dfc8dc0972 bridge bridge local

27c06defdb9d dev bridge local

708d4a2432fd host host local

0e356843766c none null local

Placing containers on a network

We will create a named container on this network. It will be reachable with its name, search.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
$ docker run -d --name search --net dev elasticsearch
aec474a67e5d12490f503a9ab209cd6074f0b7ddcb12ee783476b3476ad2764a

Communication between containers

Now, create another container on this network.

$ docker run -ti --net dev alpine sh

Unable to find image 'alpine:latest' locally

latest: Pulling from library/alpine

2aecc7e1714b: Pull complete

Digest:
sha256:0b94d1d1b5eb130dd0253374552445b39470653fb1a1ec2d81490948876e462c

Status: Downloaded newer image for alpine:latest

/ #

From this new container, we can resolve and ping the other one, using its assigned name:

/ # ping search

PING search (172.18.0.2): 56 data bytes

64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.136 ms

64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.063 ms

64 bytes from 172.18.0.2: seq=2 ttl=64 time=0.092 ms

3 packets transmitted, 3 received, 0% packet loss, time 2000ms rtt


min/avg/max/mdev = 0.114/0.149/0.221/0.052 ms

root@0ecccdfa45ef:/#

Resolving container addresses

In Docker Engine 1.9, name resolution is implemented with /etc/hosts, and updating it each time
containers are added/removed.

[root@0ecccdfa45ef /]# cat /etc/hosts


.0ecccdfa45ef
.localhost
::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters
.search
.search.dev

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
In Docker Engine 1.10, this has been replaced by a dynamic resolver.
(This avoids race conditions when updating /etc/hosts.)

Connecting multiple containers together

 Let's try to run an application that requires two containers.


 The first container is a web server.
 The other one is a redis data store.
 We will place them both on the dev network created before.

Running the web server

10) The application is provided by the container image jpetazzo/ trainingwheels.


11) We don't know much about it so we will try to run it and see what happens!

Start the container, exposing all its ports:

$ docker run --net dev -d -P jpetazzo/trainingwheels

Check the port that has been allocated to it:

$ docker ps -l

Test the web server

 If we connect to the application now, we will see an error page:

 This is because the Redis service is not running.


 This container tries to resolve the name redis.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
Note: we're not using a FQDN or an IP address here; just redis.

Start the data store

✓ We need to start a Redis container.


✓ That container must be on the same network as the web server.
✓ It must have the right name (redis) so the application can find
it.

Start the container:

$ docker run --net dev --name redis -d redis

Test the web server again

 If we connect to the application now, we should see that the app is working correctly:


 When the app tries to resolve redis, instead of getting a DNS error, it gets the IP address
of our Redis container.

A few words on scope

 What if we want to run multiple copies of our application?


 Since names are unique, there can be only one container named redis at a time.
 We can specify --net-alias to define network-scoped aliases, independently of the
container name.

Let's remove the redis container:

$ docker rm -f redis

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
And create one that doesn't block the redis name:

$ docker run --net dev --net-alias redis -d redis

Check that the app still works (but the counter is back to 1, since we wiped out the old Redis
container).

Names are local to each network

Let's try to ping our search container from another container, when that other container is not on
the dev network.

$ docker run --rm alpine ping search ping: bad address 'search'

Names can be resolved only when containers are on the same network. Containers can contact
each other only when they are on the same network (you can try to ping using the IP address to
verify).

Network aliases

We would like to have another network, prod, with its own search container. But there can be
only one container named search! We will use network aliases.

A container can have multiple network aliases. Network aliases are local to a given network
(only exist in this network). Multiple containers can have the same network alias (even on the
same network). In Docker Engine 1.11, resolving a network alias yields the IP addresses of all
containers holding this alias.

Creating containers on another network

Create the prod network.

$ docker create network prod

5a41562fecf2d8f115bedc16865f7336232a04268bdf2bd816aecca01b68d5 0c

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
We can now create multiple containers with the search alias on the new prod network.

$ docker run -d --name prod-es-1 --net-alias search --net prod elasticsearch

38079d21caf0c5533a391700d9e9e920724e89200083df73211081c8a356d771

$ docker run -d --name prod-es-2 --net-alias search --net prod elasticsearch


1820087a9c600f43159688050dcc164c298183e1d2e62d5694fd46b10ac3bc3d

Resolving network aliases

Let's try DNS resolution first, using the nslookup tool that ships with the alpine image.

$ docker run --net prod --rm alpine nslookup search Name: search

Address 1: 172.23.0.3 prod-es-2.prod Address 2: 172.23.0.2 prod-es-1.prod


(You can ignore the can't resolve '(null)' errors.)

Connecting to aliased containers

Each ElasticSearch instance has a name (generated when it is started). This name can be seen
when we issue a simple HTTP request on the ElasticSearch API endpoint.

Try the following command a few times:

$ docker run --rm --net dev centos curl -s search:9200

"name" : "Tarot",

...

Then try it a few times by replacing --net dev with --net prod:

$ docker run --rm --net prod centos curl -s search:9200

"name" : "The Symbiote",

...

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
Good to know...

Docker will not create network names and aliases on the default bridge network.
Therefore, if you want to use those features, you have to create a custom network first.
Network aliases are not unique: you can give multiple containers the same alias on the same
network.
In Engine 1.10: one container will be selected and only its IP address will be returned when
resolving the network alias.
In Engine 1.11: when resolving the network alias, the DNS reply includes the IP addresses of all
containers with this network alias. This allows crude load balancing across multiple containers
(but is not a substitute for a real load balancer).
In Engine 1.12: enabling Swarm Mode gives access to clustering features, including an advanced
load balancer using Linux IPVS.
Creation of networks and network aliases is generally automated with tools likeCompose
(covered in a few chapters).

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
13. Local Development Workflow with Docker

Using a Docker container for local development

Never again:

• "Works on my machine"
• "Not the same version"
• "Missing dependency"

By using Docker containers, we will get a consistent development environment.

Our "namer" application

The code is available on https://github.com/jpetazzo/namer.


The image jpetazzo/namer is automatically built by the Docker Hub .

Let's run it with:

$ docker run -dP jpetazzo/namer

Check the port number with docker ps and open the application.

Let's look at the code

Let's download our application's source code.

$ git clone https://github.com/jpetazzo/namer

$ cd namer $ ls -1 company_name_generator.rbconfig.ru docker-compose.yml


Dockerfile Gemfile

Where's my code?
According to the Dockerfile, the code is copied into /src :

FROM ruby

MAINTAINER Education Team at Docker <[email protected]>

COPY . /src

WORKDIR /src

RUN bundler install

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
CMD ["rackup", "--host", "0.0.0.0"]

EXPOSE 9292

We want to make changes inside the container without rebuilding it each time.
For that, we will use a volume.

Our first volume


We will tell Docker to map the current directory to /src in the container.

docker run -d -v $(pwd):/src -p 80:9292 jpetazzo/namer

The ­d flag indicates that the container should run in detached mode (in the background).
The ­v flag provides volume mounting inside containers.
The ­p flag maps port 9292 inside the container to port 80 on the host.
jpetazzo/namer is the name of the image we will run.
We don't need to give a command to run because the Dockerfile already specifies rackup.

Mounting volumes inside containers

The ­v flag mounts a directory from your host into your Docker container. The flag structure is:

[host-path]:[container-path]:[rw|ro]

✓ If [host­path] or [container­path] doesn't exist it is created.


✓ You can control the write status of the volume with the ro and rw
options.
✓ If you don't specify rw or ro, it will be rw by default.

There will be a full chapter about volumes!

Testing the development container

Now let us see if our new container is running.


$ docker ps

Viewing our application

Now let's browse to our web application on:

http://<yourHostIP>:80

We can see our company naming application.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
Making a change to our application

Our customer really doesn't like the color of our text. Let's change it.

$ vi company_name_generator.rb

And change

color: royalblue;

To: color: red;

Refreshing our application

Now let's refresh our browser:

http://<yourHostIP>:80

We can see the updated color of our company naming application.

Improving the workflow with Compose

You can also start the container with the following command: $ docker­compose up ­d

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
This works thanks to the Compose file, docker­compose.yml:

www: build: . volumes:

.:/src

ports:

80:9292

Why Compose?

 Specifying all those "docker run" parameters is tedious.


 And error­prone.
 We can "encode" those parameters in a "Compose file.
 When you see a docker­compose.yml file, you know that you can use docker­compose up.
 Compose can also deal with complex, multi­container apps. (More on this later.)

Workflow explained

We can see a simple workflow:

 Build an image containing our development environment. (Rails, Django...)


 Start a container from that image.Use the ­v flag to mount source code inside the container .
 Edit source code outside the containers, using regular tools.(vim, emacs, textmate...)
 Test application.(Some frameworks pick up changes automatically.Others require you to Ctrl­C +
restart after each modification.)
 Repeat last two steps until satisfied.
 When done, commit+push source code changes. (You are using version control, right?)

Debugging inside the container


Docker introduced a feature called docker exec.

It allows users to run a new process in a container which is already running.If sometimes you find
yourself wishing you could SSH into a container: you can use docker exec instead.You can get a shell
prompt inside an existing container this way, or run an arbitrary process for automation.

docker exec example

$ # You can run ruby commands in the area the app is running and more!

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
$ docker exec -it <yourContainerId> bash

root@5ca27cf74c2e:/opt/namer# irb

irb(main):001:0> [0, 1, 2, 3, 4].map {|x| x ** 2}.compact => [0, 1, 4, 9, 16]

irb(main):002:0> exit

Stopping the container

Now that we're done let's stop our container.

$ docker stop <yourContainerID>

And remove it
$ docker rm ourContainerID>

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
14. Using Docker Compose for Development Stacks

Dockerfiles are great to build a single container. But when you want to start a complex stack made of
multiple containers, you need a different tool. This tool is Docker Compose.
In this lesson, you will use Compose to bootstrap a development environment.

Compose for Development Stacks


What is Docker Compose?

Docker Compose (formerly known as fig) is an external tool. It is optional (you do not need Compose to
run Docker and containers) but we recommend it highly! The general idea of Compose is to enable a very
simple, powerful onboarding workflow:

• Clone your code.


• Run docker-compose up.
• Your app is up and running!

Compose overview

This is how you work with Compose:

 You describe a set (or stack) of containers in a YAML file called docker-compose.yml.
 You run docker-compose up.
 Compose automatically pulls images, builds containers, and starts them.
 Compose can set up links, volumes, and other Docker options for you.
 Compose can run the containers in the background, or in the foreground.
 When containers are running in the foreground, their aggregated output is shown.

Checking if Compose is installed

If you are using the official training virtual machines, Compose has been pre-installed.
You can always check that it is installed by running:

$ docker-compose --version

Installing Compose

If you want to install Compose on your machine, there are (at least) two methods.
Compose is written in Python. If you have pip and use it to manage other Python packages, you can
install compose with:

$ sudo pip install docker-compose

(Note: if you are familiar with virtualenv, you can also use it to install Compose.)

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
If you do not have pip, or do not want to use it to install Compose, you can also retrieve an all-in-one
binary file:

curl -L \
https://github.com/docker/compose/releases/download/1.8.0/docker-
compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

$ chmod +x /usr/local/bin/docker-compose

Launching Our First Stack with Compose

First step: clone the source code for the app we will be working on.

$ cd

$ git clone git://github.com/jpetazzo/trainingwheels

...

$ cd trainingwheels

Second step: start your app.

$ docker-compose up

Watch Compose build and run your app with the correct parameters, including linking the relevant
containers together.

Launching Our First Stack with Compose


Verify that the app is running at http://<yourHostIP>:8000.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
Stopping the app
When you hit ^C, Compose tries to gracefully terminate all of the containers. After ten seconds (or if you
press ^C again) it will forcibly kill them.

The docker-compose.yml file


Here is the file used in the demo:

version: "2"

services:

www:

build: www

ports:

- 8000:5000

user: nobody

environment:

DEBUG: 1

command: python counter.py

volumes:

- ./www:/src

redis:

image: redis

Compose file versions

Version 1 directly has the various containers (www, redis...) at the top level of the file.

Version 2 has multiple sections:

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
➢ version is mandatory and should be "2".
➢ services are mandatory and corresponds to the content of the version 1 format.
➢ networks are optional and can define multiple networks on which containers can be placed.
➢ volumes are optional and can define volumes to be used (and potentially shared) by the
containers.

Containers in docker-compose.yml
Each service in the YAML file must contain either build, or image.

 build indicates a path containing a Dockerfile.


 image indicates an image name (local, or on a registry).
The other parameters are optional.
They encode the parameters that you would typically add to docker run. Sometimes they have several
minor improvements.

Container parameters

• command indicates what to run (like CMD in a Dockerfile).


• ports translate to one (or multiple) -p options to map ports. You can specify
local ports (i.e. x:y to expose public port x).
• volumes translates to one (or multiple) -v options.

You can use relative paths here.

For the full list, check http://docs.docker.com/compose/yml/.

Compose commands
We already saw docker-compose up, but another one is docker-compose build. It will execute docker
build for all containers mentioning a build path. It is common to execute the build and run steps in
sequence:

$ docker-compose build && docker-compose up

Another common option is to start containers in the background:

$ docker-compose up –d

Check container status

It can be tedious to check the status of your containers with docker ps, especially when running multiple
apps at the same time.
Compose makes it easier; with docker-compose ps you will see only the status of the containers of the
current stack:

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
$ docker-compose ps

Name Command State Ports

----------------------------------------------------------------------------------------

trainingwheels_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp

trainingwheels_www_1 python counter.py Up 0.0.0.0:8000->5000/tcp

Cleaning up
If you have started your application in the background with Compose and want to stop it easily, you can
use the kill command:

$ docker-compose kill

Likewise, docker-compose rm will let you remove containers (after confirmation):

$ docker-compose rm

Going to remove trainingwheels_redis_1, trainingwheels_www_1

Are you sure? [yN] y

Removing trainingwheels_redis_1...

Removing trainingwheels_www_1...

Alternatively, docker-compose down will stop and remove containers.

$ docker-compose down

Stopping trainingwheels_www_1 ... done

Stopping trainingwheels_redis_1

... done Removing trainingwheels_www_1 ... done Removing


trainingwheels_redis_1

... done

Special handling of volumes

Compose is smart. If your container uses volumes, when you restart your application,
Compose will create a new container, but carefully re-use the volumes it was using previously.
This makes it easy to upgrade a stateful service, by pulling its new image and just restarting your
stack with Compose.

Visualpath Training & Consulting.


Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.
Visualpath Training & Consulting.
Flat no: 205, Nilgiri Block,Aditya Enclave, Ameerpet, Hyderabad, Phone No: - +91-970 445 5959, 961 824 5689 E-
Mail ID : [email protected], Website : www.visualpath.in.

You might also like