Docker is a software that allow us to do operating system visualization.
It uses the Linux kernel to isolate process from their host machine and other process. The docker itself is written with Go.
You can install docker on windows and Macintosh, but it in order to work on those system, it will install a linux VM.
And all docker images are images of linux variants. The linux kernel of the container is the same as the host kernel (in the case of Windows and Macintosh the same for the linux vm and the container).
One of the main reason to use docker is that it solve the problem of “it works on my machine”, this is because the when you package your app inside the docker the environment is the same. Anther reason is that it solve dependency conflict. For example if one component of you app need version 3 pf python, and the other part need version 2.7 of python, then you just put them in different container, and for every container you put the correct version of python.
The biggest advantage of docker over VM is the small overhead in the start time of the docker and small footprint it has on memory and cpu consumption.
The memory consumption of docker container is almost the same has the memory consumption of the process that run inside it, unlike VM that duplicate the whole OS and has a far more memory and CPU consumption.
A different between docker and traditional VM, is what happen when the docker stop and restart, in docker all change disappear. You can however create volume or mount directory to the host, in these cases, changes that are made to the mounted directories and volumes are persistence.
So in essence docker image are immutable, every time you start it, all previous change (that have happened inside the container) disappear.
An important thing to know about docker container is that all process inside the container are running on the host machine are jailed, this is strongly different from traditional VM where you wont be able to see the process in host machine. In the case of docker, using ps to scan all processes in the host machine will show all the processes in the docker container as well.
So to summarize the points above:
- Docker images are immutable, so if you stop and the run again container, all changes to the file system disappear, unless you are explicitly using volumes or mount directories to the host. So if you started docker container, deleted everything, stopped the container and then started it again, all changes would disappear, unless you used volume or mount directory to the host.
- The linux kernel is shared between all containers and the host.
- All the process inside docker containers are visible in the host and can be detected by using ps command. The processes are running in the host machine but they are jailed and see only the container file systems and the resources that docker show them.
Installing docker is easy.
sudo apt-get install docker.io
After you install docker you need to be root to work with docker.
If you want to work with docker with your user and not root then you need to add your user to the group docker
sudo usermod -aG docker < userName >
After you add your user to the docker group then you can work with docker without sudo command.
So the first thing you would like to do is to retrieve information about the docker server and the container, you do this by running:
This command will tell how many containers are running and their current state.
An example of the output:
oren@ubuntuTesting:~$ docker info Containers: 0 Running: 0 Paused: 0 Stopped: 0 Images: 0 Server Version: 1.12.1 Storage Driver: aufs Root Dir: /var/lib/docker/aufs Backing Filesystem: extfs Dirs: 0 Dirperm1 Supported: true Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: host null bridge overlay Swarm: inactive Runtimes: runc Default Runtime: runc Security Options: apparmor Kernel Version: 4.4.0-57-generic Operating System: Ubuntu 16.04.1 LTS OSType: linux Architecture: x86_64 CPUs: 1 Total Memory: 740.3 MiB Name: ubuntuTesting ID: O2KN:4GIF:D6ZA:GP22:DSAF:QA33:QCM7:HQEN:CCFE:FT3N:3MWC:VM7X Docker Root Dir: /var/lib/docker Debug Mode (client): false Debug Mode (server): false Registry: https://index.docker.io/v1/ WARNING: No swap limit support Insecure Registries: 127.0.0.0/8
Docker has images and containers, image is an immutable state of the file system of the container (not include mounted volume).
In order to create container you run images and docker create container from the image.
The image itself is consist from immutable layer, the layer themselves can be shared between different images and save disk space.
Every image has a name and a tag, separated with columns.
When you ask docker to use images and don’t specify the tag, then docker will use latest as the image tag.
docker run <imageName> to create and run a container from imageName.
if we want to interact with the container we can add -i (for interactive) and -t (for terminal).
So in order to create a container from ubuntu image and interact with it, we can run:
docker run -it ubuntu
Since we didn’t supplied tag, docker will create the container form ubuntu:latest.
This is how the output look like:
oren@ubuntuTesting:~$ docker run -it ubuntu Unable to find image 'ubuntu:latest' locally latest: Pulling from library/ubuntu b3e1c725a85f: Pull complete 4daad8bdde31: Pull complete 63fe8c0068a8: Pull complete 4a70713c436f: Pull complete bd842a2105a8: Pull complete Digest: sha256:7a64bc9c8843b0a8c8b8a7e4715b7615e4e1b0d8ca3c7e7a76ec8250899c397a Status: Downloaded newer image for ubuntu:latest root@ebeecb1b874e:/#
if you want to exist the container without stopping it or making it finish, then press
CTL + p + q . Using this keys will take you out of the container to the host but wont finish the container.
If docker can not find the images local then it will try to fetch it from dockerhub, therefore the line
Unable to find image 'ubuntu:latest' locally
Every container has as ID, in the example above the container id start with ebeecb1b874e.
We can use this id in order to reattach to the container or to mange them, but a better way is to give the container a semantic name.