For many Docker enthusiasts, the
docker run command is a familiar one. It's often the first Docker command we learn. The
docker run command is the command used to launch Docker containers. As such, it's familiar to anyone starting or running Docker containers on a daily basis.
In this article, we will get back to the basics and explore a few simple
docker run examples. During these examples, we will use the standard redis container image to show various ways to start a container instance.
While these examples may be basic, they are useful for anyone new to Docker.
Just Plain Ol' Docker Run
The first example is the most basic. We'll use the
docker run command to start a single redis container.
$ docker run redis 1:C 16 Jul 08:19:15.330 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
We can see that not only did we start the container, but we did so in "attached" mode. By default, if no parameters or flags are passed, Docker will start the container in "attached" mode. This means that the output from the running process is displayed on the terminal session.
It also means that the terminal session has been hijacked by the running container, if we were to press
ctrl+c, for example. We would then stop the redis service and as such stop the container.
If we leave the terminal session alone and open another terminal session, we can execute the
docker ps command. With this, we can see the container in a running status.
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1b83ac544e95 redis "docker-entrypoint..." 2 minutes ago Up 2 minutes 6379/tcp loving_bell
docker ps command above, we can see quite a bit about the running container, but one thing sticks out more than others. That is the name of the container:
By default, Docker will create a unique name for each container started. The names are generated from a list of descriptions (ie, "boring" or "hungry") and famous scientists or hackers (ie, Wozniak, Ritchie). It's possible however, to specify a name for our container. We can do so by simply using the
--name parameter when executing
$ docker run --name redis redis 1:C 16 Jul 08:22:17.296 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
In the above example, we used the
--name parameter to start a redis container named
redis. If we once again run the
docker ps command, we can see that our container is running, this time with our specified name.
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 67bbd0858ef5 redis "docker-entrypoint..." 30 seconds ago Up 27 seconds 6379/tcp redis
--name to limit the number of containers running
--name parameter is a useful option to know. Not only does naming a container make it easier to reference the container when executing Docker commands, but naming the container can also be used to control the number of containers that run on a single host.
To explain this in a bit more detail, let's see what happens if we try to start another container named redis without stopping the previous
$ docker run --name redis redis docker: Error response from daemon: Conflict. The container name "/redis" is already in use by container "67bbd0858ef5b1782875166b4c5e6c1589b28a99d130742a3e68f62b6926195f". You have to remove (or rename) that container to be able to reuse that name.
We can see one very important fact about running containers: With Docker, you are not allowed to run multiple containers with the same name. This is useful to know if you need to run multiple instances of a single container.
It is also useful to know this limitation if you wish to only run one instance of a specific container per host. A common use case for many users of Docker is to use the
--name as a safety check against automated tools launching multiple Docker containers.
By specifying a name within the automated tool, you are essentially ensuring that automated tools can only start one instance of the specified container.
!Sign up for a free Codeship Account
Using -d to Detach the Container
Another useful parameter to pass to
docker run is the
-d flag. This flag causes Docker to start the container in "detached" mode. A simple way to think of this is to think of
-d as running the container in "the background," just like any other Unix process.
Rather than hijacking the terminal and showing the application's output, Docker will start the container in detached mode.
$ docker run -d redis 19267ab19aedb852c69e2bd6a776d9706c540259740aaf4878d0324f9e95af10 $ docker run -d redis 0f3cb6199d442822ecfc8ce6a946b72e07cf329b6516d4252b4e2720058c702b
-d flag is useful when starting containers that you wish to run for long periods of time. Which, if you are using Docker to run services, is generally the case. In attached mode, a container is linked with the terminal session.
-d is a simple way to detach the container on start.
Using -p to Publish Container Ports
In the examples above, all of our redis containers have been inaccessible for anything outside of the internal Docker service. The reason for this is because we have not published any ports to connect to redis. To publish a port via
docker run, we simply need to add the
$ docker run -d -p 6379:6379 --name redis redis 2138279e7d29234defd2b9f212e65d47b9a0f3e422165b4e4025e466f25bbc2b
In the above example, we used the
-p flag to publish the 6379 port from the host to the container to port 6379 within the container. This means anyone connecting to this host over port 6379 will be routed to the container via port 6379.
The syntax for this flag is
host_ip:host_port:container_port, with the host IP being optional. If we wanted to see what ports were mapped on a previously running container, we can use the
docker ps command.
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2138279e7d29 redis "docker-entrypoint..." 22 seconds ago Up 21 seconds 0.0.0.0:6379->6379/tcp redis
We can see that our host is listening across all interfaces (
0.0.0.0) on port 6379, and that traffic is being redirected to port 6379 within the container.
Another useful tip regarding the
-p flag is that you are able to specify it multiple times. This comes in handy if the container in question uses multiple ports.
Using -v to Mount Host Volumes
The last option we are going to explore is one that can be very important to anyone running containers that require persistent storage. This option is the
-v flag is used to define volume mounts. Volume mounts are a way to share storage volumes across multiple containers. In the example below, we are sharing the
/tmp/data directory on the host as
/data to the container.
$ docker run -d -p 6379:6379 --name redis -v /tmp/data:/data redis 23de16619b5983107c60dad00a0a312ee18e526f89b26a6863fef5cdc70c8426
The example above makes it to where anything written to
/data within the container is actually accessing
/tmp/data on the host. The same is true of anything being written to
/tmp/data on the host; that data will also be available within
/data in the container.
We can see this if we look within the
/tmp/data directory on the host.
$ ls /tmp/data/ dump.rdb
This option is important for anyone running a database or application that requires persistence within Docker.
It is important, because any data that is written within the container is removed as soon as the container itself is removed. Essentially, if we were to simply spin up a redis instance without using volume maps, we could populate data within that redis instance. However, as soon as the container that hosts that instance is removed, the data within that redis instance is also removed.
By using volume mounts, we can keep the data located on the host (as seen above), allowing any other redis container that uses that same volume mount to start where the previous container left off.
Performance implications of volume mounts
Another key aspect of volume mounts is that the write speed to a volume mount is far greater than the write speed within the container's filesystem. The reason for this is that the default container filesystem uses features such as thin provisioning and copy-on-write. These features can introduce latency for write-heavy applications.
By using a host-based volume mount, the containerized application can achieve the same write speeds as the host itself.
In this article, we covered quite a few options for the
docker run command. However, while these options are key, they only scratch the surface of the available options to
docker run. Some of the options are complex enough to deserve an article unto themselves.