Not so long ago I had to do research on how to run a dotnet application on Docker. Thanks to that I’ve learned the basics of Docker. The text below is based on the notes that I’ve written down in the process.

Docker quickstart series


  1. Docker quickstart – installation
  2. Docker quickstart – running containers – standard, interactive, daemon modes


What is Docker

Docker is an application packaging platform and runtime. Each image (Docker’s name for application package) consists of layers containing application dependencies and the application itself. Layers may contain system, runtime, libraries, etc. What’s important is that each layer is readonly. Thanks to packaging one may start several separated instances of one image on one physical machine.

How it differs from a virtual machine

Taking the above into account one could say that Docker is in fact a virtual machine. Well, things are getting a bit complicated there.

Docker is not a virtual machine yet it virtualizes some resources. For example, each container has an isolated file system or network (although it may be changed). On the other hand, each process has its hook on the host machine. Just take a look at “ps” output:

As you can see, starting Docker container (instance of image) host has started several new processes. I am talking about PIDs 19495, 19510, 19522 and 19535. The container that I’ve started is a dotnet core web host. That’s the reason why there are running dotnet processes. As I don’t have dotnet installed on host, it proves that the container processes are delegated to Docker’s host.

When you consider the above, the difference between Docker and a virtual machine is getting clearer. It is that VMs are virtualizing whole hardware whilst Docker exposes “bare-metal” devices as they are seen by the host machine.

Another difference is that setting up a VM requires you to store whole stack used by your application. I mean that VMs have to store a lot more data than containers. VMs are using virtual storage devices that contain bootloader, operating system, drivers, libraries and last but not least your hosted application. If you want to scale an application horizontally you have to clone a complete virtual drive image. Docker architecture limits the amount of data that has to be stored for a container. By providing readonly layers it makes it possible to reuse the image, so several containers may run using single image. Atop of all readonly layers Docker inserts a read/write persistence layer. That persistence together with a container config (network, volumes, environment vars, etc.) is what differs the containers from each other. See the console output below to notice that running ubuntu under Docker consumed about 130MB for image, then starting new instance adds under 150KB to the disk usage. The reason is that both containers are using one image. The only stored information is the difference between the image and the container. It works a bit like snapshots in VMs but with Docker you can run several snapshots simultaneously.

Installing Docker Engine

There are two ways to install Docker.
The easy way using shell script provided by Docker inc.
The hard way if you don’t trust third party shell scripts. The hard way can be found at Docker page.

While learning Docker I’ve used the easy way so I will describe this one here. Using the easy method you don’t have to care about any dependencies or setting up the system (except for installing it of course). As I am no Linux geek, I’ve decided to use the easy way.

Basically all you have to do to install Docker is to call:

wget -qO- | sh

What it does is:

  1. “wget -qO-” downloads the script from ‘’. The ‘-q’ flag stands for quiet, and means that ‘wget’ won’t write progress to standard output (stdout). The ‘-O’ flag redirects downloaded content to the specified file. By using ‘-O‘ we basically say that ‘wget’ should write the output to stdout which I use in the next step.
  2. By using the pipe sign I redirect the output of the ‘left command’ to the ‘right command’s standard input stream (sdtin).
  3. ‘sh’ processes data from stdin. Due to the fact that I’ve redirected the ‘wget’ stdout to the ‘sh’, the ‘sh’ command executed the downloaded script.

After the script processing ends you may call ‘docker -v’ to verify installation.

badamiak@dockerhost:~$ docker -v
Docker version 1.11.2, build b9f10c9

Test run

After installation you may want to try to run your first container. Docker provides an official image for Hello-World application. All you have to do is to call ‘docker run hello-world’. If everything is working right you will see the line ‘Hello from Docker!’ in the result.


After reading through this post you should be able to run your own instance of Docker and also a sample application contained in the hello-world image.
I hope that I’ve also explained the basic concepts behind Docker and its architecture.
In the next part of this tutorial I will cover running a parametrized container, setting up virtual networks and attaching host directories as volumes to a container.
If you have any questions or remarks please write a comment and I shall soon address your concerns.

One thought on “Docker quickstart – pt 1 – installation

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.