Docker quickstart series
- Docker quickstart – installation
- Docker quickstart – running containers – standard, interactive, daemon modes
In the previous part of Docker quickstart series, I’ve covered basic concepts behind Docker and its installation. I’ve also shown how to run a simple test container named “hello world” with the command:
docker run hello-world
In this part of Docker quickstart, I will start with running containers in interactive mode with volume mounting and port forwarding. Then I will show you how to attach to a running container, read a containers output and briefly explain container configuration info.
docker run <image>
In the first part of this quickstart, I’ve shown you how to test if your instance of Docker is running by starting a sample container. The CLI (command line interface) call I’ve used then was ‘run’.
In the most basic call, without any options, it just starts an image and executes its ENTRYPOINT or CMD. ENTRYPOINT and CMD are dockerfile directives and will be covered in another part of this quickstart. For now, all you have to know is that it runs default command specified for container.
with specific command
To start Docker with user specified command call:
docker run <image> <command>
Let’s say that all you want to do with your container is to test if it can connect with host. For that I will use the most basic tool which is ping. All I have to do to start ping from container is to call:
docker run debian ping 172.17.0.1 -c 5
badamiak@dockerhost:~$ docker run debian ping 172.17.0.1 -c 5 PING 172.17.0.1 (172.17.0.1): 56 data bytes 64 bytes from 172.17.0.1: icmp_seq=0 ttl=64 time=0.096 ms 64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.069 ms 64 bytes from 172.17.0.1: icmp_seq=2 ttl=64 time=0.077 ms 64 bytes from 172.17.0.1: icmp_seq=3 ttl=64 time=0.067 ms 64 bytes from 172.17.0.1: icmp_seq=4 ttl=64 time=0.062 ms --- 172.17.0.1 ping statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.062/0.074/0.096/0.000 ms
So we’ve specified that Docker should create container using Debian image, then inside the container it should run ping to dockerhost with 5 packets.
Another way to run a container is to start it in interactive mode. For example, if you start the Debian image, it will immediately stop. It’s because no action command was specified to run.
Now let’s assume that you want to interact with your container. To do so, all you have to do is to add -i and -t switches to Docker’s ‘run’ command. -i switch runs the container in interactive mode, meaning your input will be redirected to the container. -t switch is used to emulate the terminal.
Command pattern there will be:
docker run -it <image> <command>
For example: as bash is the default command for Debian image one can skip the <command>. So, to start it in interactive mode all you have to do is type:
docker run -it debian
badamiak@dockerhost:~$ docker run -it debian root@2f41c9ed26cb:/# exit exit badamiak@dockerhost:~$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2f41c9ed26cb debian "/bin/bash" 7 seconds ago Exited (0) 4 seconds ago admiring_hoover badamiak@dockerhost:~$
As you can see, I am connected to Debian container CLI logged in as root.
At this point, I got interested in what would happen, if -i or -t was passed independently. Details on what happens under such conditions are here: Docker ‘run’ -i/-t independently.
Up to this moment every time we’ve started a container, after it’s been finished, it was left on the drive, ready to be reexecuted. Such behavior is not always expected, e.g. if we are not going to reuse existing containers, as with time the count of stored containers that are not running will stack up to a tremendous level and make it hard to manage containers. The easiest way to get rid of an exited container is to remove it right after its execution stops. Fortunately, we can specify that the instance of an image we create with ‘run’ command should be removed when it finishes as part of ‘run’ command itself. The switch that determines that is –rm.
docker run --rm debian
Now let’s see an example. First, I list all containers that are stored in exited status:
badamiak@dockerhost:~$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES badamiak@dockerhost:~$
So I start with no stored containers. Then I start the Docker container three times without –rm switch:
badamiak@dockerhost:~$ docker run debian badamiak@dockerhost:~$ docker run debian badamiak@dockerhost:~$ docker run debian badamiak@dockerhost:~$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6252be2356ed debian "/bin/bash" 4 seconds ago Exited (0) 3 seconds ago modest_allen 1e10ce08a831 debian "/bin/bash" 17 seconds ago Exited (0) 15 seconds ago thirsty_lamarr bca7d5ae1d47 debian "/bin/bash" 22 seconds ago Exited (0) 20 seconds ago berserk_engelbart badamiak@dockerhost:~$
As you can see on the attached console listing, I have three stored containers in exited state, one for each time I’ve called Docker ‘run’. Then I start another Debian container, but this time with –rm switch:
badamiak@dockerhost:~$ docker run --rm debian badamiak@dockerhost:~$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6252be2356ed debian "/bin/bash" 15 seconds ago Exited (0) 14 seconds ago modest_allen 1e10ce08a831 debian "/bin/bash" 28 seconds ago Exited (0) 27 seconds ago thirsty_lamarr bca7d5ae1d47 debian "/bin/bash" 33 seconds ago Exited (0) 32 seconds ago berserk_engelbart badamiak@dockerhost:~$
As you can see, despite having started another container, it is not visible on containers list as it got removed right after the execution finished.
This is just one of two main methods for removing existing containers. That one that is more than enough as long as you don’t use daemon containers, or you don’t reuse already existing containers. I will describe the other method another time in an article about containers management.
Up to this point, I’ve described how to run a container that does its job and then exits, but sometimes you need to run your container as a background service. This container mode called ‘daemon’ or ‘detached state’ may be required for file hosting services, database servers, monitoring services or other continuously running applications. To run such an application you follow the ‘docker run’ command with ‘-d’ switch.
What the -d switch does, is it starts the application and then detaches the console from Docker process. For example, if you want to start nginx server you probably want it to run even if you disconnect from your Docker hosting machine. To achieve that, you have to detach your console from the nginx instance. To do that you just simply call:
docker run -d nginx
In the result Docker will return the container id and detach the console.
In the excerpt below, first, I simply start an nginx container. Console is attached to the process. Then I break the program with “ctrl + c”. Ps returns no results for nginx processes, as these were killed by break. After that, I start the detached container. What Docker does there is what follows:
- starts the nginx container
- detaches the console, which means that container process is running in an independent context
- prints out the container id.
Now, when I call ps, it returns that nginx processes are running. I may now exit from the console and the nginx processes will still be running in the background.
root@dockerhost:~# docker run nginx ^Croot@dockerhost:~ps -e | grep nginx root@dockerhost:~# docker run -d nginx 67071102820d1b37e7673517f2e2b928e10e1dc02bcb424ea28e19f7db37746d root@dockerhost:~# ps -e | grep nginx 8513 ? 00:00:00 nginx 8530 ? 00:00:00 nginx root@dockerhost:~#
In this part I’ve covered how to start a container in three different modes which are:
- standard – start task, exit container after task is finished
- interactive – start task that takes input and/or prints user queries, then exit container after task is finished
- daemon – start task then detach terminal and leave container running in the background
In the next post I will cover how to start a container that:
- shares data with its host
- is exposed to the internet
- connects with other containers using virtual network
- has initialized environmental variables