DevOps

The Basics of the Docker Run Command

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

From the 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: loving_bell.

Using the --name Parameter

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.

$ 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

Using --name to limit the number of containers running

The --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 redis container.

$ 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.

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

The -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.

Using -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 -p flag.

$ 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.

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.

Summary

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.

Reference: The Basics of the Docker Run Command from our WCG partner Ben Cane at the Codeship Blog blog.

Benjamin Cane

Benjamin Cane is a systems architect in the financial services industry. He writes about Linux systems administration on his blog and has recently published his first book, Red Hat Enterprise Linux Troubleshooting Guide.
Subscribe
Notify of
guest

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

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button