Over the past years, Docker has become an essential technology used in software development. Developers, DevOps, Companies has adopted this new technology quite fast.
Nothing to be surprised about, its containerization concept has made it easy to set up, share and deploy software projects.
In this article we’ll what Docker is, what a container is and how to start playing with it.
What is Docker ?
Docker is a software platform for building applications based on containers — small and lightweight execution environments that make shared use of the operating system kernel but otherwise run in isolation from one another.
What are containers ?
One of the goals of modern software development is to keep applications on the same host or cluster isolated from others. This can be difficult, thanks to the packages, libraries, and other software components required for them to run.
One solution to this problem has been virtual machines, which keep applications on the same hardware entirely separate, and reduce conflicts among software components and competition for hardware resources to a minimum. But virtual machines are bulky—each requires its own OS, so is typically gigabytes in size—and difficult to maintain and upgrade.
Containers, by contrast, isolate applications’ execution environments from one another, but share the underlying OS kernel. They’re typically measured in megabytes, use far fewer resources than VMs, and start up almost immediately.
They can be packed far more densely on the same hardware and spun up and down massively with far less effort and overhead.
Start running containers
First things first, in order to use Docker and play with containers you need Docker daemon running in your machine.
You can visit this website and find the best fit for your platform and system
One of the first things I always like to show is how easy is to start up a new web server using Docker.
$ docker pull nginx Using default tag: latest latest: Pulling from library/nginx 743f2d6c1f65: Pull complete 6bfc4ec4420a: Pull complete 688a776db95f: Pull complete Digest: sha256:1d0dfe527f801c596818da756e01fa0e7af4649b15edc3eb245e8da92c8381f8 Status: Downloaded newer image for nginx:latest
Just by running that command a new nginx docker container will be downloaded into your host so right after you can start up the nginx web server, just typing:
$ docker run -p 80:80 nginx
You can know visit
and you’ll see something like shown in the attached screenshot.
As you can see in the console you’ll see the nginx logs whenever you visit that URL:
172.17.0.1 - - [10/May/2019:13:24:02 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15" "-" 172.17.0.1 - - [10/May/2019:13:24:02 +0000] "GET /favicon.ico HTTP/1.1" 404 154 "http://localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15" "-" 2019/05/10 13:24:02 [error] 7#7: *2 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost", referrer: "http://localhost/"
If you click
Ctrl + C
nginx container will stop and the web server as well.
Let’s continue with our nginx example and learn how we can run our nginx in detached mode, which means, we won’t need to keep the console opened to keep the container running. It will continue running in the background, as a daemon.
$ docker run -p 80:80 -d nginx a7284d38009c1af92c1e31499bd57c3aa2d2b39b697c0369221ba18c0b66f341
We added the
flag to run this container in the background.
The output should simply be the new container’s ID.
Let’s see how our newly created container is doing.
Just by typing:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a7284d38009c nginx "nginx -g 'daemon of…" 49 seconds ago Up 47 seconds 0.0.0.0:80->80/tcp eager_mendel
You’ll see a lot of information of the container. One surprising thing is the name, isn’t it ? Docker by default assigns random names to containers, you can manage that by passing the name you want, for instance:
docker run --name docker-nginx -p 80:80 -d nginx
argument you can define the name you want.
To be able to stop your container you can execute this command:
$ docker stop a7284d38009c
To delete the already stopped container
$ docker rm a7284d38009c
Detached containers & logs
Let’s start again a new nginx container.
$ docker run --name docker-nginx -p 80:80 -d nginx 64f3a3f077dd23214ff308b321c474d6852539056e3f3be85adfb21fedcbca43
This newly created container is running in detached mode, show how we can get its logs ?
Just by using
$ docker logs 64f3a3f077dd 172.17.0.1 - - [10/May/2019:13:34:29 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15" "-"
If you use the argument
you’ll get follow log output
As you can see on every access to the web server you’ll see the new entry in the logs.
There’s one other thing I’d like to show you is how you can get inside the container to perform advanced operations.
As you’ll see later more or less a container is just a functional linux system with some packages pre-installed. Following with our nginx example, in our case could be a Debian Stretch system with nginx pre-installed and pre-configured.
Just by typing:
$ docker exec -t -i 64f3a3f077dd /bin/bash root@64f3a3f077dd:/#
You’ll be logged in inside the container as root user, as you can see it’s a linux system.
root@64f3a3f077dd:/# ls / bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@64f3a3f077dd:/# cat /etc/issue Debian GNU/Linux 9 \n \l
Now that you’re inside the container you can do whatever you want or need, such get the logs or install new packages. The problem with doing that is when the container gets destroyed, all installed packages will be destroyed as well.
Building a Web Page to Serve on Nginx
Let’s create a simple web page to be served by a new nginx container.
$ mkdir docker-nginx $ cd docker-nginx/ $ touch index.html
We’ll use nano for editing index.html file. Just add this content and save the file
Linking the Container to the Local Filesystem
In this section, we’ll put it all together. We’ll start our Nginx container so it’s accessible on the Internet over Port 80, and we’ll connect it to our website content on the server.
Docker allows us to link directories from our virtual machine’s local file system to our containers.
To do this, we use the
flag to map a folder from our local machine (~/docker-nginx) to a relative path in the container (/usr/share/nginx/html).
$ docker run --name docker-nginx -p 80:80 -d -v ~/docker-nginx:/usr/share/nginx/html nginx 80ee624a452a41588b2d16b3fd78a66288781ecf8f138eb99350bea4ba9c20d8
If you now visit
you’ll see our new web page created.
If you now edit your web page in your local file system and refresh the page in the browser, you’ll get new changes !
You now have a running Nginx container serving a custom web page. It was quite a useful starting guide to know Docker and containers doing something with them.