Docker is not confusing as you think. Start learning Docker right now before it’s too late and here’s a guide for you.
Docker is one of many technologies that are so popular right now, and maybe almost all software engineers want to learn about it. You can see the growing number of Docker usage from their website.
Docker Index: Dramatic Growth in Docker Usage Affirms the Continued Rising Power of Developers …
Developers have always been an integral part of business innovation and transformation. With the massive increase in…
Docker itself is an amazing technology that solves some of our problems as a software engineer. In this article, I will try to explain the simplest explanation and guide about Docker.
“It works on my machine!”
You must have heard that sentence many times whenever you run an application on a different machine. There are many possibilities that can cause that problem to arise, but some of them are:
- Installed a different version of dependencies at the other machine.
- Forgot the “working” configuration of the application.
- Forgot to install certain dependency at the other machine.
That’s when Docker become the solution.
“We need time to prepare the environment for the application.”
If your application is needed to run on multiple machines, you as the engineer will ask our boss for time to preparing your machine to be able to run the application. This “time” can be reduced or may be removed when you are using Docker.
“My machine specification is not good enough to emulate a Virtual Machine.”
There are multiple occasions that make you want to emulate another OS inside your machine to develop your application. And we know that emulating another OS is a heavy task and not all machines capable of doing that. Docker can somehow replace the usage of virtual machines.
What is Docker?
Docker is a tool designed to make it easier to create, deploy, and run applications by using containers. Containers allow us to deploy any application within 1 package that already consists of the required library and dependencies.
Docker runs on top of its host kernel machine but still isolated between container so it is good to make sure each of the application configuration, libraries, and dependencies don’t affect the other application.
Docker VS Virtual Machine
You can say that Docker is a lightweight version of Virtual Machine. One of the main reasons is Docker doesn’t create an individual OS for every container that has been created. Docker is still using and sharing the host OS kernel into all of the running containers.
From the diagram above, you can know that Docker is getting rid of 1 layer (the Guest OS kernel) and it makes Docker container and its application will have less memory usage and startup time.
Even though Docker is better in terms of memory and performance, Docker still has its own flaw compared to the Virtual Machine, it is the security. When a certain application that runs inside a Docker container got hacked or has a vulnerability, it can affect the Host machine because they still share the same OS kernel, which is the Host.
When to Use Docker?
Docker is indeed a powerful tool, but you need to know when exactly we need to use Docker so it won’t make our development and deployment become more efficient.
When You Have 1 Application for Multiple Machine
Having 1 application running on multiple machines is one of sign that you might need to use Docker. Installing the app, installing its dependencies and configuring it will take a lot of time if we need to do it repetitively on all of your machine that needs to run the application.
Using Docker, you just need to install Docker on each machine, write a simple Docker’s related file, and then you can run our application based on the file that you have been written. The file contains your application and its required dependencies.
When You Want to Test Distributed Architecture
When your company becomes bigger, your application will also grow bigger. A bigger application will eventually make you try to implement the distributed architecture, or popularly know as Microservice architecture.
Configuring all of your separated machines to work within a Microservice architecture will take some time and Docker can help you reduce that time. By installing Docker in your main machine, you can just deploy our application into multiple containers that acts as an individual machine.
With Docker, testing microservice architecture inside a single machine is quite simple and effective. Each of Docker’s containers will become an individual machine that can interact with each other and our own host OS with Docker’s own network mechanism.
How to Use Docker?
Write a Dockerfile
Dockerfile is the main configuration file if you want to use Docker. It contains multiple things such as your application, your application’s dependencies, and even your application’s OS requirement.
To create a Dockerfile, there is some syntax that you need to learn. Below is a simple Dockerfile that contains the most frequently used syntax.
- FROM — This syntax is used at the beginning of our Dockerfile. It will define the base environment that your application needed to run. The provided Dockerfile is needing a Go environment, so it use Golang with ver 1.14 with Linux Alpine kernel.
- RUN — Run command will execute certain commands that exists inside the OS kernel that you have been used based on the previous FROM syntax.
- WORKDIR — WORKDIR syntax will change your current working directory inside the Docker container. It is like
cdin Linux to navigate to the targeted directory.
- COPY <host target location> <container target location> — COPY syntax will copy data from the host machine to the created Docker container. The target location can be written as relative PATH or absolute PATH. The provided example is copying all of the files inside the Host that is located in the same directory as the Dockerfile, and put it inside the provided working directory that has been declared before.
- ENV — This syntax is used to set an environment variable inside the created container.
- EXPOSE <Port Number> — Expose, just like the name will expose a certain port number to the outside, whether the Host or another container.
- CMD [command 1, arg 1, arg 2, …] — This syntax is written if your container has a default Command that needed to run the first time the container is running. The provided example is want to run a Go application, therefore it will execute a binary that has been created with the binary’s own argument.
Those are just the frequently used syntax in a Dockerfile, for more about it you can see it at the Docker website.
Installing Docker is a very simple task, follow the guide from the website and choose your host machine OS that will be installed with Docker.
Building a Docker Image
A finished Dockerfile is needed to be built into Docker Image, so it can be executed into a Docker container. Building a Docker Image is quite simple, below is the simplest Docker CLI command that you will need to run in the command line.
docker build -t <application_name>:<application_version> .
. character is defining the context of the docker container. It will make our current directory as the context. The
-t flag is an optional because it will define the tag and version of the Docker image.
View Existing Image
A list of all existing Docker image inside your Host machine can be viewed by using the Docker command on your CLI:
It will return all of the existing images in the Host machine:
elasticsearch 7.10.1 558380375f1a 3 weeks ago 774MB
openapitools/openapi-generator-cli latest 097683db8380 6 weeks ago 136MB
qrunner-queue-connector_rabbitmq-worker latest 8a3e43b8ddf8 7 weeks ago 93.6MB
<none> <none> 8f2564949537 7 weeks ago 1.05GB
qrunner-api_dispatcher latest 22ea784fbef1 7 weeks ago 138MB
mariadb 10.3.25 5a5644205c65 2 months ago 388MB
rabbitmq 3.8.9-management-alpine 727f04dff442 2 months ago 150MB
gcr.io/datadoghq/agent 7 242ba6349d09 2 months ago 695MB
datadog/agent 7 242ba6349d09 2 months ago 695MB
docker/desktop-kubernetes kubernetes-v1.19.3-cni-v0.8.5-critools-v1.17.0 7f85afe431d8 2 months ago 285MB
golang 1.15.3 4a581cd6feb1 2 months ago 839MB
debian stretch-slim fd6779905c35 2 months ago 55.3MB
ravioli latest b292a28a06f5 2 months ago 261MB
mongo 4.4.1 ba0c2ff8d362 3 months ago 492MB
As we said many times, an application that is running via Docker is deployed inside a Docker container. The container can be run with a docker image that has been built inside our machine or an image that exists on another server/repository.
To run a Docker container here is the simplest command that we need to type inside the CLI:
docker run --name <container_name> -e "<ENV value that want to be set>" -p <HOST port:Container port> <image_name:image_tag>
- — name, this will be the name of our created container. If you don’t specify it, Docker will generate a funny custom name.
- -e, this is an argument to set up an ENV value that needs to be configured at the start time when running a container.
- -p, to make your application accessible outside its own container, this is a must argument. Make sure you already EXPOSE the port inside the container before exposing it with this argument.
This is an advanced usage of Docker. You can skip this step for now, but If you:
- Have multiple applications that depend on each other.
- Have multiple arguments that needed to be used when running the container.
Then you may need to write a Docker compose file, and use it. Docker compose file is written in
yml format. Because of the YAML usage, make sure the indentation of the file is properly formatted to prevent any error. Below is an example of a Docker compose file.
- version — this will define the version of the Docker compose.
- networks — this will define the network type that your containers will use between them.
- services — these are all our containers that will be running when you execute the docker-compose.
To elaborate on what are those key and value inside the YAML file below is the description of them:
After finished writing the file, you can run the docker-compose with its own simple CLI command,
# Running single container
docker-compose up <service_name># Running single container on background
docker-compose up -d <service_name># Running all the configured container
View Existing Container
Docker container can be run as a background process. You can see all running containers by using below Docker CLI command:
the above command will only return the currently running container, if you want to see all the container inside the Host machine, you can use:
docker ps -a
Both of them will give you a result something like this:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5e9cffe129e8 elasticsearch:7.10.1 "/tini -- /usr/local…" 10 days ago Exited (255) About a minute ago 0.0.0.0:9200->9200/tcp, 9300/tcp elastic7
94291be25f1a elasticsearch:6.7.2 "/usr/local/bin/dock…" 10 days ago Exited (143) 10 days ago elastic6
d08fb781be76 datadog/agent "/init" 5 weeks ago Exited (255) 4 weeks ago 8125/udp, 0.0.0.0:8125-8126->8125-8126/tcp dd-agent
239b22fde708 mvertes/alpine-mongo:4.0.6-1 "/root/run.sh mongod…" 7 weeks ago Exited (255) 6 weeks ago 28017/tcp, 0.0.0.0:27021->27017/tcp qrunner_mongo
9c36d70b20fb mariadb:10.3.25 "docker-entrypoint.s…" 2 months ago Exited (255) 7 weeks ago 0.0.0.0:3307->3306/tcp mariadb
b75dee403e93 mongo:4.4.1 "docker-entrypoint.s…" 2 months ago Exited (255) 3 weeks ago 0.0.0.0:27018->27017/tcp mongo441
60f2aef5df79 aongko/pubsub-emulator "gcloud beta emulato…" 2 months ago Exited (137) 2 months ago ravioli_pubsub
8fff7f0531b9 93e193026f44 "/bin/sh -c 'go buil…" 7 months ago Exited (2) 7 months ago festive_chaum
3c04da386e4a 8b4515c22a70 "/bin/sh -c 'go buil…" 7 months ago Exited (2) 7 months ago condescending_hertz
0ae7dbc21f53 php:7.4 "docker-php-entrypoi…" 10 months ago Up About a minute 9000/tcp app
d69968af3b25 mysql:5.7 "docker-entrypoint.s…" 10 months ago Up About a minute 0.0.0.0:3306->3306/tcp, 33060/tcp db
bd32f5a031fc nginx:alpine "nginx -g 'daemon of…" 10 months ago Up About a minute 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp webserver
Stop Running Container
The very simple way to stop running containers is by exiting the Docker application at the Host machine. But, if you want to stop an individual running container, you can do it by using the below command:
docker container stop <container_id>
Delete Existing Container
Using Docker will eventually make your Host storage become full. Deleting unused containers will be a good behavior for you to do.
docker container rm <container_id>
Repetitive work is boring and not effective. Docker’s team also knows about this and they provide us a “place” to use and share docker images that are used very frequently by another engineer.
Docker Hub is an online repository that hosts a Docker image that has been built by many people and organizations. This repository is very useful when we need an image that is also used by other engineers around the world that have previously write a Dockerfile and build an image from it. This repository is open to public and private, so if we think our image will be useful to other people, uploading it to the Docker Hub will be a great contribution to the community.
Final Verdict, Should You Use Docker?
The final verdict, should you use Docker?
Docker is a great tool, but if you don’t actually need it, it will just make your development and deployment process more complicated and also takes more time. Re-read this article and research more about Docker with your teammate to decide about it.
Thank you, and happy coding! 😁
More Docker References: