Docker is one of those services that you always hear about but may have never used. I never used Docker in college, and I actually never heard of it until I began researching the field of DevOps. Knowing how to use Docker is a quintessential element of becoming a part of a modern development team. My goal of this post is to help the reader gain an understanding of what Docker is, to learn why enterprise teams are adopting it today, and how to get started using Docker.
If you already know how to use Docker, consider reading my post about managing containers using Kubernetes.
Questions to answer:
- What problems does Docker solve?
- What are containers?
- What is the difference between a container and a VM?
- What is the difference between images and containers?
- How does Docker help create applications?
Why Docker?
The need for Docker arises from virtual machines on servers being used at large scales. Take a large business for example. For a business that uses hundreds of servers with a cluster of virtual machines for each of their platforms, maintaining these machines is a full-time job. Each server has to have an OS installed, it needs upgrades and patches from time to time, and then dependencies for the applications each machine uses also have to be installed.
You can see why this quickly becomes very complex. Manually configuring these servers is not feasible, so many companies keep a list of servers that they programmatically update. This can work, however the list of servers is shared between a team of people, and this list does not always stay up to date. Some servers never receive updates and consequentially errors may arise which impact system performance. Finding one faulty server in a room of hundreds can also be a troubleshooting nightmare. How does Docker solve this?
Docker to the rescue!
Rather than running applications on virtual machines, you can upload Docker images to your server. When an image fails, you just upload a new one. There is no need to worry about configuration because the image exists as an exact replica of the original configuration. In this way, you do not have to worry about installing application dependencies or OS patches because they have already been configured in your Docker image. The Docker setup frees you from treating servers as pets, constantly monitored and cared for, to something more ephemeral; It is okay if the image fails, you can just replace it. "What is an image, and why can it be a better fit than virtual machines? You might ask." This term will make more sense as we move forward.
Docker is also great for developers. It means no more "It works on my machine" since all the developers are developing with the same stack maintained in the Docker file.
How does Docker streamline the development process?
CI/CD: You can consistently test and deploy your code to different environments in the development process (staging, user acceptance testing, production) without the hassle of configuring various testing environments.
Versioning: Docker also helps with versioning, as you can save different versions of software on repositories and check them out later if needed. This eliminates the need for changing versions of software when running an older version of an application.
Roll Forward: When defects are found, there is no need to patch or update the application. You just need to use a new image.
What is the difference between an image and a container?
Docker images and containers are closely related, however they are distinct. Docker images are immutable, meaning they cannot be changed. I have explained previously that these images can be uploaded to servers in place of running applications directly on an OS. Images contain the source code, libraries, dependencies, tools and other files that the application needs to run. When using Docker, we start with a base image. Because images can become quite large, images are designed to be composed of layers of other images to allow a minimal amount of data to be sent when transferring images over the network.
The instance of an image is called a container. Containers are running instances with top writable layers, and they run the actual applications. When the container is deleted, the writable layer is also deleted but the underlying image remains the same. The main takeaway from this is that you can have many running containers off of the same image. A good way to think about images and containers is with this metaphor: Images are the recipe to make a cake, and containers are the cakes you bake. You can make as many cakes as your resources allow you with a recipe; you can make as many containers as your resources will allow you with an image.
What is the difference between virtual machines and containers?
Consider the layout of a typical VM fleet: Virtual machines are managed through a hypervisor, which runs on a host OS that is installed on server hardware. The hypervisor virtualizes hardware that virtual machines use to run their operating systems (Guest OS). So basically the server has a host OS, and the virtual machines themselves have a complete operating system installed.
What makes a container different is that the container does not have a Guest OS. Instead, the container actually virtualizes the operating system. Inside this container you can build whatever you want. The advantages to using containers over virtual machines are the fast boot up time and their portability.
Building images with Dockerfiles
As you can see, Docker helps ease the hassle of installation and configuration. Let's look at a sample Docker command:
sudo docker run docker/whalesay cowsay Hello-World!
As you can see, the docker image did not initially exist locally so it had to be pulled from docker/whalesay. You can also see that the image consists of multiple layers e190868d63f8, 909cd34c6fd7, etc. To create an image, we can create a Dockerfile. Once this file is completed, we will use docker build [OPTIONS] PATH | URL | -
to create our image.
A Dockerfile can be created using touch Dockerfile
and can be edited using your favorite text editor. Notice that this file is created without an extension, this is intentional.
In your Dockerfile, type the following code:
The FROM statement declares what image your new image will be based on. For this sample project, I will be using the ubuntu image. However if you want to create a Docker image from scratch, you can simply write FROM scratch
.
LABEL is used to apply meta data to Docker objects. In this case, you can use LABEL to specify the maintainer of the Docker image. MAINTAINER was once used but this is since deprecated.
RUN is used to execute commands during the building of the image, while CMD is executed only when the container is created out of the image.
In the directory of your Dockerfile, type docker build .
The first time each command is executed, each command will be executed. Each command in the Dockerfile is cached, so if you edit the file it will only need to build for edited command. After editing the echo command of our Dockerfile, we will also give the Docker image a name and the 'latest' tag.
docker build -t helloworld:latest .
To run your image, first find the image name by running docker images
.
Note that you can run a Docker image by its image ID or its name and tag. If you run by name only, Docker will automatically run by the 'latest' tag.
docker run helloworld:latest
and docker run 4d6c8eea04c9
produce the same output in this case.
And there you have it! You have created your first Docker image. You can find other images on https://hub.docker.com and documentation at https://docs.docker.com/
Extra Credit!
I suggest pushing your newly created docker image to DockerHub if you would like to share your Docker images. First, create a DockerHub account at https://hub.docker.com
Log in to your DockerHub account using the CLI:
docker login
You can also log out from your CLI using:
docker logout
Furthermore, you can push your newly created docker image by first tagging it.
docker tag <image> helloworld:latest <DOCKER_HUB_USERNAME>/dockerhub:myfirstimagepush
Next, push the docker image:
docker push <DOCKER_HUB_USERNAME>/dockerhub:myfirstimagepush
You should receive a SHA-256 hash indicating the push was successful.
If you think you're ready to manage your Docker containers using Kubernetes, read my post about Kubernetes and then read about OpenShift, the industry's most secure and comprehensive enterprise-grade container platform!
Conclusion
I hope that this post can help anyone who feels like they aren't ready to learn about Docker. Often times, the most difficult part of getting something done is starting it. Please let me know if this helped or if I missed anything!
P.S.
I am currently looking for a job in DevOps! If you know someone who is hiring entry-level DevOps engineers please send them my resume which can be found at https://smcgown.com and https://www.linkedin.com/in/steven-mcgown/
Thank you!
Top comments (10)
Thanks for the awesome article! Very informative and loved the recipe / cake analogy for images / containers. I found it through your Kubernetes for dummies article, which I what I originally searched.
Glad you liked it! Thinking of it this way was a big breakthrough when I first started learning it.
I hope you all learned something while reading this.
I am currently looking for a job in DevOps! If you know someone who is hiring entry-level DevOps engineers please send them my resume which can be found at smcgown.com
R u going to write new articles on docker
In the future I suppose I could. What would you like to see specifically?
Docker networking and volumes.Real world simple project implementation
I'll do it. Stay tuned
Good post to kick off with the path of Docker. I'm getting the ball rolling with the DevOps role tasks and love to read different point of views of this branch of developing. Thanks for sharing your knowledge and exp.
So glad you enjoyed!
Thank you Steven, this a direct and great article to understand Docker basics! I'll make sure to share with my team since it helped me so much. 😊