Docker For Developers

DZone 's Guide to

Docker For Developers

Learn your way around Docker machines and how to get them working the way you want them to.

· Cloud Zone ·
Free Resource

Originally published Nov. 6, 2016

Image title

A whale of an application.

Docker is a container technology which wraps up a piece of software in a complete filesystem that contains everything it needs to run: code, runtime, system tools, system libraries — anything you can install on a server. This guarantees that it will always run the same, regardless of the environment it is running in.

Docker is a tool that is designed to benefit both developers and system administrators, making it a part of many DevOps (developers + operations) toolchains. For developers, it means that they can focus on writing code without worrying about the system that it will ultimately be running on. It also allows them to get a head start by using one of the thousands of programs already designed to run in a Docker container as a part of their application.

You may also enjoy: What is Docker?

As a developer you do not need to know every detail Docker administration, all you need to know is going to be explained in this article.

I assume you can download and install Docker for your machine using the official Docker page.

Docker runs behind a virtual machine both on Windows and Mac. So we first have a look at docker-machine which manages Docker's virtual machine.

We use docker-machine ls for checking our docker-machine/s.

$ docker-machine ls
default - virtualbox Stopped Unknown

The "default" docker-machine is created as a result of the installation process. You can drop it and create a new one if you want.

In order to drop it, we use the following command.

$ docker-machine rm default
About to remove default
Are you sure? (y/n): y
Successfully removed default

As we run the "ls" command again, we will see nothing.

$ docker-machine ls

Now we will create a new docker-machine in order to proceed with our tutorial. Here, I'll name it "softlab". We will use Oracle's VirtualBox as the driver — for other drivers, you can check here.

$ docker-machine create --driver virtualbox softlab
Running pre-create checks...
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env softlab

If you want to dive into the newly created softlab docker-machine, we use docker-machine ssh softlab  

$ docker-machine ssh softlab
                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
 _                 _   ____     _            _
| |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
Boot2Docker version 1.12.3, build HEAD : 7fc7575 - Thu Oct 27 17:23:17 UTC 2016
Docker version 1.12.3, build 6b644ec
docker@softlab:~$ exit

We use the stop command to stop the docker-machine and start to start the docker-machine. See the following shell samples.

$ docker-machine stop softlab
Stopping "softlab"...
Machine "softlab" was stopped.

$ docker-machine start softlab
Starting "softlab"...
(softlab) Check network to re-create if needed...
(softlab) Waiting for an IP...
Machine "softlab" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.

We need the environment variables set in order to configure our shell to use Docker. We can get those variables with the env command.

$ docker-machine env softlab
export DOCKER_HOST="tcp://"
export DOCKER_CERT_PATH="/Users/dursun/.docker/machine/machines/softlab"
export DOCKER_MACHINE_NAME="softlab"
# Run this command to configure your shell:
# eval $(docker-machine env softlab)

As stated in the output, we need to set these variables via  eval $(docker-machine env softlab) .

$ eval $(docker-machine env softlab)

Now we are ready to run Docker containers on our docker-machine. First, we will run the hello world container.

$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c04b14da8d14: Pull complete 
Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker Hub account:

For more examples and ideas, visit:

Let's check our containers with the ps command.

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

Nothing, because the "hello world" container just started and stopped, and the ps command shows only the running containers. If we want to see all the containers regardless of whether they are running, we should pass the -a parameter.

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
462d32f52d54        hello-world         "/hello"            10 seconds ago      Exited (0) 9 seconds ago                       pensive_tesla

Now let's try a web server.

$ docker run -d -p 80:80 --name webserver nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
43c265008fae: Pull complete 
e4c030a565b1: Pull complete 
685b7631c1ce: Pull complete 
Digest: sha256:dedbce721065b2bcfae35d2b0690857bb6c3b4b7dd48bfe7fc7b53693731beff
Status: Downloaded newer image for nginx:latest


  •  -d  means the container should run detached. The container will run in the background and print the container ID.

  •  -p  is used to configure the container's port reflection on the host. Remember, the host is the docker-machine, not your localhost. Here, the 80 port of the container will be reflected to the host's 80 port. If we hit to the host:80 it would hit to the container's port 80.

  •  --name  is used to assign a name to our container. If you omit this parameter, Docker will make it up for you, like in the previous example.

Let's run ps  again:

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                         NAMES
dc58b43c56d0        nginx               "nginx -g 'daemon off"   9 seconds ago      Up 10 seconds>80/tcp, 443/tcp   webserver

See the status column says that our webserver containers, which are created from the Nginx image, are still running. Now I am going to hit the host's port 80 and hope to see Nginx's welcome page. Before that, I need to find the host's IP. I will use the ip  command on the docker-machine.

$ docker-machine ip softlab

In order to stop the webserver container, we will use the docker stop command.

$ docker stop webserver
$ docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

If you want to dive deeper, please see my article about Developing a Java 8 Spring Boot App in Docker.

Further Reading

Getting Started With Docker From a Developer Point of View

Docker For Beginners

cloud, commands, containers, docker, docker command, docker development

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}