It is often observed that the code written for our application works on the development environment but not on staging or production environment. The reasons could be missing software, system configuration, different software versions, or additional services that may hinder the application. System setups are time consuming, since there are dependencies for different platforms. Also developing distinct applications could require varying software versions. These and similar cases can be resolved with Docker.
What is Docker
Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from infrastructure so that you can deliver software quickly. Using Docker, you can manage your infrastructure in the same way that you manage your applications. Docker provides a consistent environment for the application from development through production, easing the code development and deployment pipeline.
- Virtual machine (VM) is an emulation of a computer system.
- Virtual machines are based on computer architectures and provide functionality of a physical computer.
- It imitates dedicated hardware.
- The end user has the same experience on a virtual machine as they would have on dedicated hardware.
- A hypervisor or virtual machine monitor (VMM) creates and runs virtual machines.
Hypervisor: A hypervisor is a program that enables you to host several different virtual machines on a single hardware.
A container is a lightweight, executable software package that includes everything needed to run it - code, runtime, system tools, system libraries, and settings. Deploying multiple applications via containers would require significantly less hardware than doing so via virtual machines.
Docker vs VM
- Docker does not have the overhead of a hypervisor.
- Docker shares the kernel with host machine; whereas if you use virtualization, you can create "n" number of virtual machines based on the capacity of your host, install OS for each VM, and then run/deploy your application.
- With docker, you get a performance gain compared to VM.
- Docker allows much quicker start times. E.g. 100 containers can be started, and do their work, in subsecond time. However starting the same amount of VMs would take forever because they need to boot a full OS.
Follow below commands to install Docker on ubuntu 16.04/17.04
- sudo apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual
- sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
- sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable"
- sudo apt-get update
- sudo apt-get install docker-ce
The first thing to do after installing docker is to create a docker container that will have the software we want. E.g. Apache, Mysql, PHP etc.
To run/create a docker container, we need to grab the docker image of required software.
What does a Docker image consists of?
Docker image is a snapshot of the container in which the desired software and it’s dependencies are installed .
Docker images can be pulled (downloaded) from hub.docker.com
hub.docker.com is a free portal or store of docker images.
You can visit hub.docker.com and search for the image you want. Below is the screenshot of hub.docker.com
Pull a docker image
By default docker pulls images from hub.docker.com.
Command to pull a docker image: docker pull <image_name>:<tag>
<image_name> : This is a image name you want to pull. E.g. drupal
<tag> : tag is a version of the image. E.g. 8, 8.4.
If you don’t mention this, the tag is considered as ‘latest’ by default.
E.g. docker pull drupal:8.4
Once we have downloaded/pulled the image, we are ready to create the container from pulled image.
Command to run the container:
docker run --name <my_container_name> -d <image_name>
--name <my_container_name> : This option is not mandatory. When we run a container, it is identified with a unique container id.
What if we have multiple containers?
It is difficult to identify. Hence we use option -- name. Here we can give a custom name to the container.
-d option tells docker to run the container process in background.
E.g. docker run --name my_drupal -d drupal
I have a running container of drupal but
- How do I see the status of my containers?
- How do I access my drupal site/apache on the browser? Because my browser don’t know how to connect to the docker container.
- I want to execute/write something into the container’s file system. How do I login to the container shell. E.g. In/var/www/html
- How do I copy files from my host machine to the container?
- My changes in the container file system disappear when I remove my container. What to do?
- I have run the container but it shows as stopped. What went wrong? Where do I see the logs?
See the status of containers
Once you run the container, you might want to see its status.
Docker provides command to list the docker processes (containers).
Command: docker ps
This command shows only running containers. To see all (running and stopped) containers, use -a option. E.g. docker ps –a
Access services from container to host machine
After running a container, the question that comes to mind is, how do I access apache? As we know, the apache runs on port 80 by default, and mysql runs on port 3306.
Docker provides you an option -p to export the container ports to the host port.
E.g. If you want to expose the container’s apache server, you can write -p 8888:80 while running the container. So the RUN command will look as follows.
docker run --name <my_container_name> -p 8888:80 -d <image_name>
Now you can access the apache page from your browser at http://localhost:8888
NOTE: Host port can be anything. But container port should be a valid port in order to access the service. Also make sure that the host port is free.
Login in to container shell and write to the file system
Login to the container shell, docker provides a command - docker exec
Command: docker exec -i -t <my_container_name> /bin/bash
-i : This option is necessary for interactive shell
-t : Allocate a pseudo-TTY
<my_container_name> : This is the container name you have given while running the container. You can also mention container id instead of name here.
/bin/bash : This is a shell type. This can be /bin/sh too.
Copy between host and docker container
We have seen how to login to the container shell and execute commands and create/edit files. How do we copy files from my host machine to the container?
Docker has a command to achieve this: docker cp
Command: docker cp <path_on_host> <container_name>:<path_on_container>
E.g. docker copy /var/www/html/my_project my_drupal:/var/www/html/my_project
For reverse copy (docker container to host):
docker copy my_drupal:/var/www/html/my_project /var/www/html/my_project
Mount host volumes to container
My changes in the container file system disappear when I remove my container. What to do? When you create a container, it contains everything that its image consists of. When you make some modifications to the container file system, the changes remain until the container is alive. Once you remove the container (using docker rm command) or somehow it crashes, then it does not exist anymore in the docker daemon. Next time when you create a container out of an image, the new container has a fresh copy of the contents of the image.
The solution for the above scenario is -v option in the docker run command. The option -v (--volume) is a docker feature to mount the host directory to the specified container directory. Below is the example of -v option in the docker run command.
docker run --name <my_container_name> -p 8888:80 -v /var/www/html:/var/www/html -d <image_name>
As mentioned in the above docker run command, -v /var/www/html:/var/www/html
The first part before the ‘:’ (colon) is the directory path of the host machine, and the second part after the ‘:’ is the container path where the host directory should be mounted.
I.e. docker run --name my_drupal -p 8888:80 -v <host_dir_path>:<container_dir_path> -d drupal
Here, the host directory path and container directory path need not be the same. You can mount any directory of host to any path on the container.
Docker start stop remove images commit
Few more useful commands:
- docker start: docker start <container_name> is the command to start the stopped container.
- Docker stop: docker stop <container_name> is the command to stop the running container.
- Docker rm: docker rm <container_name> is the command to remove a container. Before removing a container, it is required to be stopped first.
Docker images is the command to list all the images you have in your docker system. These are the images you have pulled from hub.docker.com or could be your own images you have built.
If you want to save the changes made in the container, you can use a command - docker commit <container_id> <new_image_name>
Here <new_image_name> is a custom name you want to give.
After running this command, you can see (using docker images) that there is a new image ready.
When you want to re-create the container, you must use the new image to get all your changes made in the previous container. Because only the new image (create by docker commit) has all your changes.
E.g. docker run --name my_drupal -d drupal
docker exec -i -t my_drupal /bin/bash (installed nodejs in container shell)
docker commit my_drupal_cont_id my_drupal_image (this is to preserver nodejs installation)
Next time when I create my drupal container with nodejs installed, I should run it like:
docker run --name my_drupal -d my_drupal_image
For more information on Docker, feel free to reach out to us at firstname.lastname@example.org!