a. Create a DockerFile . for which we have a set of guidelines of how to create a Dockerfile
b. Build the Image from DockerFile. For which we will be using a command
c. Multiple containers are created from the image. For which we will be using commands
Docker was released on March 2013 and every year they have conference on Mar.
From Sep 2020 we see WSL2 (Windows Subsytem Linux) can also be used instead of Hyper -V to start docket in windows 10 pro
We can use Visual Studio code with Docker extension as editor
we can use cmder (https://cmder.net/) as our command editor
Docker on Linux
Three main ways to install
script
store
docker-machine
get.docker.com script(latest edge release)
curl -sSL https://get.docker.com/ | sh
store.docker.com has instructions for each distro. (Debain, Red hat , Fedrora are major distribution in Linux)
RHEL (Red Hat Enterprise Linux ) only supports Docker Enterprise Edition, but CentOS will work.
Installing in a VM,Cloud instance , all are the same process
Docker changes to release cycle , product name and versioning
In 2017 docker versioning,release cycle and product names changes but features haven't. the url has more details https://docker.com/blog/docker-enterprise-edition/
Like Ubtunu version docker also started to use the version named as YY.MM
Docker Engine(the free one we all know and love) is now Docker CE (Community Edition). Notice the drop of the word
Engine.I suspect we can just call this docker now. It includes the cli client and backend daemon/service and api. daemon is a background process running in linux world. service mightbe a background process running in windows world.
Docker Data Center is now Docker EE(Enterprise Edition) and adds additional paid products and support on top of docker in three pricing tiers.
These changes don't affect Docker compose or docker Machine.
Docker version is now YY.MM based, using the month of its expected release and the first one will be 17.03.0, which is the first point of release of the 17.03 release. If any bug/security fixes are needed to that release, the first update will be 17.03.1 etc.
Docker commands
To get the docker version we have following options
docker version
docker -v
docker --version
To get the info of docker use the below command
docker info
To get the list of docker commands and Management commands just type
"docker"
Since the commands in docker are increasing, docker has organized them into Management so earlier to 2017 we used "docker run" now it will be "docker container run". If we want to use the old way it is fine for old commands but when a new command is introduced it will work only in the new format
Old style for command in docker
docker <<command>> (options)
New style for command in docker
docker <<management command>> <<command>> (options)
To get the list of commands under a management then give the command as
docker <<management command>> --help
docker container --help
docker builder --help
To get help about the command then use the below
docker <<management_command>> <<command>> --help
docker container <<command>> --help
docker image <<command >> --help
Image Vs Container
An Image is the application we want to run.
A container is an instance of that image running as a process
You can have many containers running off the same image.
Nginx is web server and we will use that as our image.
Docker's default image "registry" is called Docker Hub (hub.docker.com)
docker container run is used to start a new container from an image.The image repository will be docker hub.
docker container run --publish 80:80 nginx
a. The command looked for nginx locally in image cache but since it did not find it
so it downloaded the latest version of nginx from docker hub.
b. Created a new container from that image and prepares to start.
c. Left number is the host port and we have opened port 80 on the host IP .
d. Routes that traffic to container IP, port 80 which is the right number.
In the container no other port will be opened expect 80.
e. Starts container by using the command specified in the docker image file.
docker container run --publish 9080:80 --detach ngnix
or
docker container run --p 9080:80 --d ngnix
Used to create new container from the image and run the container in background
docker container run --publish 9080:80 --detach --name pavan_webhost ngnix
Used to create new container from the image with a name "pavan_webhost" and run it in background.
docker container stop <<container ID>>/<<container_name>>
Used to stop the container with the container ID
docker container logs pavan_webhost
Used to list the logs of the container with name pavan_webhost
docker container ls
Used to list the currently running containers.
docker container ls -a
Used to list all containers which are running and stopped
docker container rm -f <<container ID>>
Used to remove one or more container forcefully even it is running
docker container rm <<container ID>>
Used to remove one or more container which are in stopped state. To remove multiple the specify
container ID separating with space.
docker container top <<container_name>>
Used to know what process are running in container
docker container stats
Used to know the performance stats of the container which are running
docker container inspect <<container_name>>
Used to know the container config
docker container run -d --network <<network name>> --network-alias <<alias-name>> <<imagename>>
or
docker container run -d --net <<network name>> --net-alias <<alias-name>> <<imagename>>
Used to run the container in background and attach to network and have network alias sapecified
Eg:
docker container run -d --net dude --net-alias search elasticsearch:2
If we want to connect to the container for doing some configuration then we can use the following command
docker container exec -it <<container_name>> bash
docker container exec -it mysql_db bash
docker container exec -it mysql_db sh
docker container exec -t -i mysql_db sh
docker container exec -t -i mysql_db bash
Note
-it is not a single option it is actually to
-t and
-I.
Incase if the Linux distro is not having
bash then use
sh
S
tart vs Run
Run is used to create a new container from the image every time.
Start is used to start existing container which is stopped.
Container vs VM
VM and Containers have similarities but they are different
.
Containers aren't Mini-VM's
Containers are just processes
Limited to what resources Container can access
Containers Exit when process stops
To pull details about image we have Management command called
image
docker image pull <<imagename>>
To pull image from
docker image ls
to list the image which we have locally
docker image inspect <<imagename>>
To list detail information of one or more image
docker image history <<imagename>>
To show the history of an image
Whats in an Image(and what isn't)
Application binaries and dependencies
Metadata about the image data and how to run the image
Official definition: "An Image is an ordered collection of root filesystem changes
and the corresponding execution parameters for use within
a container runtime"
Not a complete OS. No kernel, kernel modules(e.g. drivers)
Small as one file (your app binary) like a golang static binary
Big as Ubuntu distro with apt, and Apache, PHP and more installed
Image have Tags which is used to identify the version.
Alpine is small when compared to Debain distribution of Linux.
Image Layers
Docker uses
UnionFilesystem mechanism
Docker Networks Default
Each container connected to a private virtual network which is called as "
bridge network"
Each virtual network routes through NAT firewall on host IP
All containers on a Virtual network can talk to each other without -p
Best practice is to create a new virtual network for each app:
network "my_web_app" for MySQL and php/apache containers
network "my-api" for mongo and nodejs containers
Make new virtual networks
Attach containers to more than one virtual network (or none)
Skip virtual networks and use host IP(--net=host)
Use different Docker network drivers to gain new abilities
Batteries Included , But Removable
Default work well in many cases but easy to swap out parts to customize it
To work on network concept in Docker we have management command called
network.
Show networks
docker network ls
Inspect a network
docker network inspect <<network name>>
Eg:
docker network inspect bridge
Create a network and we can specify customer driver but the default is bridge
docker network create --driver
docker network create <<networkname>>
docker network create my_app_net --> will create a new network with different subnet
Attach a network to container
docker network connect
Detach a network from
docker network disconnect
Docker DNS
Understand how DNS is the key to easy inter-container communication
See how it works by default with custom networks
Learn how to use --link to enable DNS on default bridge network
Docker daemon has a built-in DNS server that containers use by default
Docker defaults the hostname to the container's name, but you can also set aliases
Best Practices
Static IP's and using IP's for talking to containers is an anti-pattern, do your best to avoid it.
Creating Images/Docker file
To create an image basing on the Dockerfile we need to understand the stanza specification and below are the few and for more details look into the docker documentation (
http://docs.docker.com/engine/reference/builder/). DockerFile is read from Top to bottom.
When creating Dockerfile make sure the least changeable are present at the top. When we are building the image from the Dockerfile if the compiler identifies a change then it will try to regenerate or recompile from that step to the bottom. While compiling the DockerFile it uses cache mechanism and SHA when there is no change and it can skip that step.
We can also have multiple images from a DockerFile.
FROM
RUN
CMD
LABEL
EXPOSE -- The ports that needs to be exposed
ENV
ADD
COPY
ENTRYPOINT
VOLUME -- To store the data of the image during runtime.
USER
WORKDIR
ARG
ONBUILD
STOPSIGNAL
HEALTHCHECK
SHELL
Container Lifetime & Persistent Data
Containers are usually immutable and ephemeral.
To persistent data in Container we have two ways
Volumes
Bind Mounts
Volumes : Make special location outside of container UFS(Union Filesystem)
Bind Mounts: Maps a host file or directory to a container file or directory like file sharing
Volumes
To know the command of volume
docker volume --help
To list the volumes
docker volume ls
To remove the volumes which are not used by containers
docker volume prune
The command is used to name a volume and we can also reuse this volume for other container as well
docker container run -d --name mysqlvolume -e MYSQL_ALLOW_EMPTY_PASSWORD=true -v mysql-db:/var/lib/mysql mysql
docker container run -d --name mysqlvolume2 -e MYSQL_ALLOW_EMPTY_PASSWORD=true -v mysql-db:/var/lib/mysql mysql
Now mysqlvolume and mysqlvolume2 are going to use the same volume
Bind Mounting
Maps host file or directory to a container file or directory
Basically just two locations pointing to the same files(s)
Again , skips UFS and host files overwrite any in container
Bind Mounting are host specific so we cannot mention in the Dockerfile, must be at
container run
… run -v //c/users/bret/stuff:/path/container (Windows)
… run -v /Users/bret/stuff:/path/container( mac/Linux)
Docker Compose
Configure relationships between containers
Save our docker container run settings in easy-to-read file
Create one-liner developer environment startups
Comprised of 2 separate but related things
1. YAML (docker-compose.yml) formatted file that describes our solution options for
containers
networks
volumes
images
Environment variables
2. CLI tool
docker-compose used for local dev/test automation with those YAML files
*******************************************************************
How to create a image ?
How have the dependencies of the image?