Hello All, Today we are going to learn about Docker Basics, commands, image formation etc.

Introduction:

What exactly is Docker? Basically, Docker is a container based system for your applications. So , it wraps everything inside a container, and your application is totally isolated from the external host.

Rather than just being one part of the puzzle, Docker provides a number of components and tools to assist with the entire lifecycle management of the application. This includes the container environment, image management and orchestration.

Why use Docker?

There are number of good reasons to start using it.

Fast :Start a Docker container can be complete in as little as 50ms.This is the advantage of having such high levels of abstraction, you reduce the number of components you need to run.

One command deployments : Deploy everything in one command, and your application will be up and running.

Pre-configured Apps : At last count, there were over 13,000 applications already packaged as a Docker image.

Resource Isolation : Here all the resources are isolated from each other, so if one fails then it wont affect the other one.

Complete Platform : Rather than just being one part of the puzzle, Docker is shaping up to be a complete platform. There’s the base Engine for the containers, the Registry for image management, Compose to orchestrate complex deployments, Swarm for clustering and Machine for provisioning.

Installation

Before installing Docker , check these two requirements:

  1. Docker works on 64-bit linux

  2. RUN uname -r

Docker requires version 3.10 or higher of the linux kernel.

Update your apt sources

Login in to your machine.

sudo apt-get update

sudo apt-get install apt-transport-https ca-certificates

Add the new GPG key:

sudo apt-key adv \ --keyserver hkp://ha.pool.sks-keyservers.net:80 \ --recv-keys 58118E89F3A912897C070ADBF76221572C52609D

echo "REPO" | sudo tee /etc/apt/sources.list.d/docker.list

Note: Replace REPO with the desired repo for your operating system.

Ubuntu version                   Repository

Precise 12.04 (LTS)  deb https://apt.dockerproject.org/repo ubuntu-precise main

Trusty 14.04 (LTS)   deb https://apt.dockerproject.org/repo ubuntu-trusty main

Wily 15.10           deb https://apt.dockerproject.org/repo ubuntu-wily main
                    
Xenial 16.04 (LTS)   deb https://apt.dockerproject.org/repo ubuntu-xenial main

Since ,I am on Xenial 16.04 (LTS) , so my REPO is

deb https://apt.dockerproject.org/repo ubuntu-xenial main

sudo apt-get update

Verify that APT is pulling from the right repository.

sudo apt-cache policy docker-engine

Prerequisites by Ubuntu Version

Ubuntu Xenial 16.04 (LTS), Wily 15.10, Trusty 14.04 (LTS)

sudo apt-get update

sudo apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual

For ubuntu 12.04 use:

sudo apt-get install linux-image-generic-lts-trusty

Install the latest version

sudo apt-get update

Install Docker

sudo apt-get install docker-engine

Start Docker daemon

sudo service docker start

Verify that docker is installed:

sudo docker run hello-world

Configure Docker to start on boot

Ubuntu uses systemd as its boot and service manager 15.04 onwards and upstart for versions 14.10 and below.

sudo systemctl enable docker

Enable UFW forwarding

If you use UFW (Uncomplicated Firewall) on the same host as you run Docker, you’ll need to do additional configuration. Docker uses a bridge to manage container networking. By default, UFW drops all forwarding traffic. You must set UFW’s forwarding policy appropriately.

In addition, UFW blocks all incoming traffic by default. If you want to access the Docker Remote API from another host and you have enabled remote access, you need to configure UFW to allow incoming connections on the Docker port, which defaults to 2376 if TLS encrypted transport is enabled or 2375 otherwise. By default, Docker runs without TLS enabled. If you do not use TLS, you are strongly discouraged from allowing access to the Docker Remote API from remote hosts, to prevent remote privilege-escalation attacks.

To configure UFW and allow incoming connections on the Docker port:

Log into Ubuntu as a user with sudo privileges.

Verify that UFW is enabled. sudo ufw status

If ufw is not enabled, the remaining steps will not be helpful.

Edit the UFW configuration file, which is usually /etc/default/ufw or /etc/sysconfig/ufw. Set the DEFAULT_FORWARD_POLICY policy to ACCEPT.

DEFAULT_FORWARD_POLICY="ACCEPT"

Save and close the file.

If you need to enable access to the Docker Remote API from external hosts and understand the security implications (see the section before this procedure), then configure UFW to allow incoming connections on the Docker port, which is 2375 if you do not use TLS, and 2376 if you do.

sudo ufw allow 2376/tcp

Reload UFW. bash $ sudo ufw reload

Docker Commands

docker pull

The ‘docker pull’ command will download the image and associated layers from the Docker Repository. These layers include everything from the base operating system through to the end application. You can browse and search the images via the Docker Registry, which has over 13,000 publicly available images.

Lets pull down the latest Python image: docker pull python

This will download the latest version of python , to download some specific version try: docker pull python:2.7

docker images

The command will show you the images you just pull , but wont show the intermediate images, to see the intermediate images , try

sudo docker images -a

docker rmi

You can remove unused images using the ‘rmi’ command. You can reference the image either by the ID or the name and also the version number.

Using Containers

docker run

docker run -t -i python

docker run -t -i python Because we’ve previously pulled down the image for the latest version of Python, it could create the container and run it nearly instantly. If it was an image which you hadn’t pulled down or used before, Docker will automatically pull down the images as part of the run command.

Lets start a basic web application as a daemon (specified with the -d flag) and have a look: docker run -d -p 5050:5000 training/webapp python app.py

You’ll see that in this example, Docker automatically downloaded the images required to run it and then started.

Note : -p option maps the network port 5050 on the host to network port 5000 within the container.This is how you make the network of the container accessible to both other containers and to the world.

Run such big commands are difficult , and prone to errors , so we will use a diffrent technique to create our images and run through it.

Automating Docker Images

Dockerfile

Create a file with name Dockerfile and edit it as:

FROM ubuntu

RUN apt-get update && apt-get install -y python python-pip python-dev libmysqlclient-dev rabbitmq-server libffi-dev zlib1g-dev libssl-dev libxml2-dev libxslt1-dev

ADD ./src/ /srv/src/

WORKDIR /srv/src/

RUN pip install -r requirements.txt

Now , to build the image out of this Dockerfile use:

docker build -t (rep)/(tag) /path/to/Dockerfile

Eg. I have the repository with the name datacapture , so i will execute:

docker build -t datacapture/test .

use .(Dot) , if you are executing above command from the same directory as of your Dockerfile

The above command will build the image as datacapture/test , taking ubuntu as the base image , that is available on global Docker registry.

To better understand the Dockerfile, let me first show you my project-work flow:

--datacapture
    --src
        --main
            --helpers
            -- models
        -- requirements.txt
        -- runserver.py
    -- Dockerfile
    -- docker-compose.yml

so, as you can see my root directory is /src , so I have added my root directory inside container as /srv/src/ directory , the next command is pretty obvious ,here I am installing the requirements to my image.

Next step in the series is to make containers for our project i.e running instance of an image, so to create the container we will create another file , say docker-compose.yml ,with the following content in it:

---
mongo:
    image: mongo
    ports:
        - "27018"
        - "27017"
    expose:
        - "27017"
        - "27018"
    volumes:
        - /data/db

rabbitmq:
    image: rabbitmq
    hostname: rabbitmq
    ports:
         - "5672"
    expose:
        - "5672"
celery:
    image: datacapture/test
    command: bash -c "celery -A main.celery_app worker -l info"
    environment:
      - DEBUG=true
      - C_FORCE_ROOT=true
      - MONGO_IP=mongo
      - MONGO_PORT=27017
      - VAST_IP=0.0.0.0
      - MONGO_DB=datacapture
      - RABBITMQ_IP=rabbitmq
      - RABBITMQ_USERNAME=guest
      - RABBITMQ_PASSWORD=guest
      - QUEUE_NAME=datacapture

    links:
        - rabbitmq

datacapture_img:
    image: datacapture/test
    ports: 
      - "5000"
      - "127.0.0.1:5000:5000"
    links:
      - mongo
      - rabbitmq
      - celery
      - elasticsearch
    command: bash -c "python runserver.py"
    environment:
      - DEBUG=true
      - C_FORCE_ROOT=true
      - MONGO_IP=mongo
      - MONGO_PORT=27017
      - VAST_IP=0.0.0.0
      - MONGO_DB=datacapture
      - RABBITMQ_IP=rabbitmq
      - RABBITMQ_USERNAME=guest
      - RABBITMQ_PASSWORD=guest
      - QUEUE_NAME=datacapture

Docker-compose is a very vast topic , it has thousands of style to configure your container , here we will look only for basic docker-compose config.

Key points to remember:

image : this section defines the base image for the container

port: where the particular service will be executable.

volumes: to store the data, logs for that particular service.

expose: The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime.EXPOSE does not make the ports of the container accessible to the host.

commands: commands to be executed inside the container.

links: to bind the container to the main app: Here, we have bind the container datacapture_img with mongo,rabbitmq and celery, as you can see celery is also linked to rabbitmq.

environment: to define runtime environment variables.

NOTE -> As you can see inside environment variables we have use MONGO_IP as mongo , the reason behind that is when container starts , docker automatically binds the IP of mongo container to the datacapture_img conatiner, so that both container can sync with each other.

Now, we have completed docker-compose file , lets start our containers , and yes, docker will start the container defined inside links first , and then the main container at last, on the basis of dependency of container on each other.

Install the docker-compose package using apt-get:

sudo apt-get install docker-compose

then run the following command, from the directory where docker-compose file is present

docker-compose up

voila, your containers are up and running, your complete running project is now on your docker system.

Working with containers

Running containers is one part, but the problem comes when you have to execute certain services or commands inside the container, lets look for some more commands that will help to ease your process in better understanding of docker.

Once we’ve created a container, we can list them all with the ‘ps’ command.

docker ps

If we want to see all of them, we can use the -a flag:

docker ps -a

To inspect your images or container in detail use:

docker inspect (conatiner-id) or (docker image)

To access the container, or to log in to your container:

  1. copy the container id, from docker ps command

  2. then run docker exec -it (container id) /bin/bash , you will be now inside the running container.

Note ->

If you change anything to docker-compose file then a layer over the previous container will be formed, all the variables will be reset to their first stage , all changes made inside the container will get stashed.

TO SHARE DOCKER IMAGE FROM ONE SYSTEM TO ANOTHER:

1.sudo docker save -o /home/matrix/matrix-data.tar matrix-data where matrix-data is the image name

and matrix-data.tar is the compressed image

  1. scp matrix-data.tar root@192.168.x.x /home/ to transfer the image from your server to another server

  2. docker load -i matrix-data.tar

This is all for the Docker Basics , in the next blog we will look how to create Docker Registry.