
Its all about applications, and every application require tons of Infrastructure, which is massive waste of resources since it utilize very less % of it. I mean with Physical Machine/ram/CPU results heavy loss of cost & bla bla.. hence Hypervisor/Virtualization came into picture, where we use shared resources on top of a single physical machine and create multiple VMs to utilize more from it but still not perfect.
Docker is the solution of above problem, it can containerize your requirement & works on the principle of layered images.
working with docker is as simple as three steps:
- Install Docker-engine
- Pull the image from HUB/docker-registry
- Run image as a container/service
How containers evolved over Virtualization
whereas containers by pass gust OS from host OS in containerization & boots up in fraction of seconds
- It is not replacing the virtualization, it is just the next step in evolution (more advanced)
What is docker?
Docker is a containerization platform which can bundle up technologies and packages your application and all it dependencies together in the form of image which further you run as a service called container so as to ensure that your application will work in any environment be it Dev/Test/Prod
Point to remember
- docker images are the read-only template & used to run containers
- docker images are the build component of docker
- There is always a base image on which you layer up your requirement
- container are the actual running instances of the images
- we always create images and run container using images
- we can pull images from docker hub/registry can be public/private
- docker daemon runs on host machine
- docker0 is not a normal interface | Its a Bridge | Virtual Switch | that links multiple containers
- Docker images are registered in Docker registry & stored in docker hub
- Docker hub is docker's own cloud repository (for sharing & caring purpose of images)
key attribute of kernel used by containers
- Namespaces (PID, net, mountpoint, user) Provides Isolation
- cgroups (control groups)
- capabilities ( assigning privileges to container users)
- but each container shares common Kernel
- Rest API
- Socket.IO
- TCP
Dockerfile supports following list of variables
FROM image:tag AS name
ADD ["src",... "dest"]
COPY /src/ dest/
ENV ORACLE_HOME=/software/Oracle/
EXPOSE port, [port/protocol]
LABEL multi.label1="value1" multi.label2="value2" other="value3"
STOPSIGNAL
USER myuser
USER myuser
VOLUME /myvolume
WORKDIR /locationof/directory/
RUN write your shell command
CMD ["executable","param1","param2"]
ENTRYPOINT ["executable","param1","param2"] (exec form, preferred)
ENTRYPOINT command param1 param2 (shell form)
ENTRYPOINT script ; /bin/bash
$ docker run -it --privileged image:tag
--privileged will give all capabilities to container and lifts all the limitaion enforced by OS/device, even you can run docker inside docker with it.
Installing docker-engine onto any Ubuntu system
$ sudo apt-get update -y && apt-get install docker.io
this will install docker-engine as a linux service . check engine status by running service docker status if its running you are good to play with docker now. else start docker engine by running service docker start
check docker details installed in your system by running any of these commands
$ docker -v | docker version | docker info
Docker needs root to work for creation of Namespaces/cgroups/etc..
$ sudo gpasswd -a red docker
then restart your session, alternatively add your user to docker group
$ vi /etc/group
append your user to docker group and start using docker with your user
Function | Command |
---|---|
pull a docker image | docker pull reponame:imagename:tag |
run an image | docker run parameters imagename:tag |
list docker images | docker images |
list running containers list container even not running | docker ps |
build an image | docker build -t imagename:tag . |
remove n processes in one command | docker rm $(docker ps -a -q) |
remove n images in one command | docker rmi $(docker image -a -q) |
reset docker system | docker system prune |
create mount | docker volume create |
using mount point | docker run -it -p 8001-8006:7001-7006 --mount type=bind, source=/software/, target=/software/docker/data/ registry.docker/weblogic12213:191004 docker run -it -p 8001-8006:7001-7006 -v data:/software/ registry.docker/weblogic1036:191004 |
create network | docker network create --driver bridge --subnet=192.168.0.0/20 --gateway=192.168.0.2 mynetwork docker run -it -p 8001:8006:7001:7006 --network=mynetwork registry.docker/weblogic1036:191004 |
for more on networking | click here: networking in docker |
Setting up Jenkins Via Docker on a Linux machine
Open a terminal window and run(Provided Docker is already installed)
$ docker pull punitporwal07/jenkins
$ docker run -d -p 9090:8080 -v jenkins-data:/var/jenkins_home punitporwal07/jenkins
docker run : default command to run any docker container
-d : run the container in detached made(in background) and omit the container ID
-p : port assignation from image to you local setup -p host-port:container-port
-v : Jenkins data to be mapped to /var/Jenkins_home/ directory/volume to one of your file system
punitporwal07/jenkins: docker will pull this image from docker Hub
it will process for 2-3 mins then prompt as:
INFO: Jenkins is fully up and running
e72fb538166943269e96d5071895f31c
This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
here we are running Jenkins inside docker as a detached container you can use:
$ docker logs to collect jenkins logs
if we select to install recommended plugins which are most useful, Jenkins by default will install:
docker run : default command to run any docker container
-d : run the container in detached made(in background) and omit the container ID
-p : port assignation from image to you local setup -p host-port:container-port
-v : Jenkins data to be mapped to /var/Jenkins_home/ directory/volume to one of your file system
punitporwal07/jenkins: docker will pull this image from docker Hub
it will process for 2-3 mins then prompt as:
INFO: Jenkins is fully up and running
to access the jenkins console( http://localhost:9090 ) for the first time you need to provide admin password to make sure it was installed by admin only. & it will prompt admin password during the installation process as something like:
e72fb538166943269e96d5071895f31c
This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
here we are running Jenkins inside docker as a detached container you can use:
$ docker logs
if we select to install recommended plugins which are most useful, Jenkins by default will install:
Best practice to write a Dockerfile
How to Upload/Push your image to registry
after building your image (docker build -t imageName:tag .) do the following:
step1- login to your docker registry
$ docker login --username=punitporwal --email=punixxorwal@xxxx.com
list your images
$ docker images
step2- tag your image for registry
$ docker tag b9cc1bcac0fd reponame/punitporwal07/helloworld:0.1
step3- push your image to registry
$ docker push reponame/punitporwal07/helloworld:0.1
your image is now available and open for world, by default your images is public.
repeat the same step if you wish to do any changes in your docker image, make the changes, tag the new image, push it to you docker hub
$ docker volume create myVolume
$ docker volume ls
DRIVER VOLUME NAME
local 2f14a4803f8081a1af30c0d531c41684d756a9bcbfee3334ba4c33247fc90265
local 21d7149ec1b8fcdc2c6725f614ec3d2a5da5286139a6acc0896012b404188876
local myVolume
there after use following way to use volume feature
we can define volumes in one container and same can be share across multiple containers
to define in container 1
$ docker run -it -v /volume1 --name voltainer centos /bin/bash
to call in another container from other container
$ docker run -it --volumes-from=voltainer centos /bin/bash
we can call Volumes in a container from Docker engine host
$ docker run -v /data:/data
/volumeofYourHost/:/volumeofContainer/
to define in a Dockerfile
VOLUME /data (but we cannot bind the volume from docker host to container via this, just docker run command can do this)
PORT MAPPING
when you expose a port from Dockerfile that means you are mapping a port defined in your image to your newly launched container , use:
$ docker run -d -p 5001:80 --name=mycontaniername myimagename
when you want to change the protocol from default i.e tcp to udp , use:
$ docker run -d -p 5001:80/udp --name=mycontinername myimagename
lets say when you want to expose your image port to any specific IP address from your docker host, use:
$ docker run -d - -p 192.168.0.100:5002:80 --name=mycontaniername myimagename
when you want to map multiple ports exposed in your Dockerfile to high random available ports , use:
$ docker run -d -P --name=mycontaniername3 myimagename
to expose a port range, use:
$ docker run -it -p 61000-61006:61000-61006 myimagename:myimagetag
also you can use EXPOSE 61000-61006 in your Dockerfile
to check port mapping , use:
$ docker port myimagename
DOCKER DAEMON LOGGING
first of all stop the docker service
$ service docker stop
$ docker -d -l debug &
-d here is for daemon
-l log level
& to get our terminal back
or
$ vi /etc/default/docker/
add log-level
DOCKER_OPTS="--log-level=fatal"
then restart docker deamon
$ service docker start
best practice is to build a container first, run all the instructions one by one that you are planning to put in a Dockerfile. Once they got succeed you can put them in your Dockerfile, which will avoid you building n images from your Dockerfile again and again and save image layers as well.
Writing a docker File: ( FROM COPY RUN CMD)
a Container runs on level of images:
base image
layer1 image
layer2 image
Dockerfiles are simple text files with a command on each line.
To define a base image we use the instruction FROM
Creating a Dockerfile
a Container runs on level of images:
base image
layer1 image
layer2 image
Dockerfiles are simple text files with a command on each line.
To define a base image we use the instruction FROM
Creating a Dockerfile
- The first line of the Dockerfile should be FROM nginx:1.11-alpine (it is better to use exact version rather then writing it as latest, as it can deviate your desired version)
- COPY
- RUN
allows you to execute any command as you would at a command prompt, for example installing different application packages or running a build command. The results of the RUN are persisted to the image so it's important not to leave any unnecessary or temporary files on the disk as these will be included in the image & it will create a image for each command - CMD is used to execute any single command as soon as container launch
Life of a docker Image
write a Dockerfile > build the image > tag the image > push it to registry > pull it back to any system > run the image
vi Dockerfile:
vi Dockerfile:
FROM baseLayer:version
MAINTAINER xxx@xx.com
RUN install
CMD special commands/instructions
$ docker build -t imagename:tag .
$ docker tag 4a34imageidgfg43 punixxorwal07/image:tag
$ docker push punixxorwal07/image:tag
$ docker pull punixxorwal07/image:tag
$ docker run -it -p yourPort:imagePort punixxorwal07/image:tag
MAINTAINER xxx@xx.com
RUN install
CMD special commands/instructions
$ docker build -t imagename:tag .
$ docker tag 4a34imageidgfg43 punixxorwal07/image:tag
$ docker push punixxorwal07/image:tag
$ docker pull punixxorwal07/image:tag
$ docker run -it -p yourPort:imagePort punixxorwal07/image:tag
after building your image (docker build -t imageName:tag .) do the following:
step1- login to your docker registry
$ docker login --username=punitporwal --email=punixxorwal@xxxx.com
list your images
$ docker images
step2- tag your image for registry
$ docker tag b9cc1bcac0fd reponame/punitporwal07/helloworld:0.1
step3- push your image to registry
$ docker push reponame/punitporwal07/helloworld:0.1
your image is now available and open for world, by default your images is public.
repeat the same step if you wish to do any changes in your docker image, make the changes, tag the new image, push it to you docker hub
Volumes in Docker
first of all create volume for your docker container using command$ docker volume create myVolume
$ docker volume ls
DRIVER VOLUME NAME
local 2f14a4803f8081a1af30c0d531c41684d756a9bcbfee3334ba4c33247fc90265
local 21d7149ec1b8fcdc2c6725f614ec3d2a5da5286139a6acc0896012b404188876
local myVolume
there after use following way to use volume feature
we can define volumes in one container and same can be share across multiple containers
to define in container 1
$ docker run -it -v /volume1 --name voltainer centos /bin/bash
to call in another container from other container
$ docker run -it --volumes-from=voltainer centos /bin/bash
we can call Volumes in a container from Docker engine host
$ docker run -v /data:/data
$ docker run --volume mydata:/mnt/mqm
/volumeofYourHost/:/volumeofContainer/
to define in a Dockerfile
VOLUME /data (but we cannot bind the volume from docker host to container via this, just docker run command can do this)
when you expose a port from Dockerfile that means you are mapping a port defined in your image to your newly launched container , use:
$ docker run -d -p 5001:80 --name=mycontaniername myimagename
when you want to change the protocol from default i.e tcp to udp , use:
$ docker run -d -p 5001:80/udp --name=mycontinername myimagename
lets say when you want to expose your image port to any specific IP address from your docker host, use:
$ docker run -d - -p 192.168.0.100:5002:80 --name=mycontaniername myimagename
when you want to map multiple ports exposed in your Dockerfile to high random available ports , use:
$ docker run -d -P --name=mycontaniername3 myimagename
to expose a port range, use:
$ docker run -it -p 61000-61006:61000-61006 myimagename:myimagetag
also you can use EXPOSE 61000-61006 in your Dockerfile
to check port mapping , use:
$ docker port myimagename
DOCKER DAEMON LOGGING
first of all stop the docker service
$ service docker stop
$ docker -d -l debug &
-d here is for daemon
& to get our terminal back
or
$ vi /etc/default/docker/
add log-level
DOCKER_OPTS="--log-level=fatal"
then restart docker deamon
$ service docker start
Br
Punit