1. Overview

Docker is open-source software that’s widely used for containerization. Containers share the resources of a single operating system, so they consume fewer resources than virtual machines.

Once we create a Docker image, we can run a container using the created image.

In this tutorial, we’ll discuss several methods of running a Docker image as a container.

2. Using docker run

In this section, we’ll discuss running containers with the docker run command.

We’ll use the following image:

$ docker images
REPOSITORY          TAG               IMAGE ID            CREATED      SIZE
image1              6.0               a8c6eeb0557e        1 week ago   1.61GB

The docker images command shows the available images. The name of the image we’ll use is image1. Its tag is 6.0.

2.1. Using Without Any Options

The most basic way of running a container is just using the image name and the command to run. It runs the command in a new container:

$ docker run image1:6.0 /bin/bash
$ echo $?
0

We seem to be successful in starting the container. The exit status was 0. We specified to use the tagged version of image1 using image1:6.0. In this case, the tag of the image is 6.0.

If we don’t specify any tags, docker run looks for a special tag name called latest. It corresponds to an image that’s built without a tag name.

The /bin/bash part of docker run was the command to run when the container was started.

Let’s check whether the container is running:

$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

We used the docker ps command to find the running containers. Although we were successful in starting the container, there seem to be no running containers. Normally, the container exits immediately after the command is executed. So, in our example, the container just ran /bin/bash and exited.

2.2. Removing the Container Automatically

docker ps shows only the running images. However, the -a option displays all the containers, including the running and stopped ones:

$ docker ps -a
CONTAINER ID   IMAGE       COMMAND       CREATED         STATUS                     PORTS   NAMES
789386223d03   image1:6.0  "/bin/bash"   5 minutes ago   Exited (0) 5 minutes ago           trusting_mclean

The container we ran before is in the list. A container’s file system is preserved even after it exits.

If we want to remove a container automatically when it exits, we can use the –rm option of docker run. But let’s remove the stopped container using docker rm first:

$ docker rm 789386223d03
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

We used the short container ID, 789386223d03, while deleting the container with docker rm. Docker assigns a container ID while starting the container. The output of docker ps -a showed that we successfully removed the container, as there are no containers in the list now.

Now, let’s start a container using the –rm option:

$ docker run --rm image1:6.0 /bin/bash
$ echo $?
0
$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
$ docker ps –a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

We successfully started the container as the exit status of docker run was 0. The output of docker ps showed that the container isn’t within the list of running containers because it immediately exited after running the command /bin/bash. It wasn’t listed when we listed all containers with docker ps -a either, since we started the container using the –rm option.

2.3. Running in Interactive Mode

What if we don’t want the container to exit immediately after it’s started? Of course, we can run a never-ending script within the container while starting the container. However, we can also achieve this by running the container in the interactive mode. We must use the -i option for the interactive mode:

$ docker run --rm –i image1:6.0 /bin/bash
pwd
/root
hostname
aba1c3fec064
exit
$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

When we ran the container using the -i option of docker run, it started the process /bin/bash. It also attached the standard input, standard output, and the standard error of the process to the console. Therefore, the container was running, and we could interact with the container.

When we ran the pwd command, we saw that we were in the /root directory within the container.

Running the hostname command showed that the automatically assigned name of the container by Docker was aba1c3fec064.

Finally, we exited from the container using the exit command.

After exiting from the container, running docker ps showed that the container wasn’t running anymore.

2.4. Allocating a Pseudo-TTY

The -t option of docker run allocates a pseudo-tty.  A pseudo-terminal is a device that functions as a physical terminal. The -t option is generally used together with the –i option:

$ docker run --rm –it image1:6.0 /bin/bash
[root@f24280d7464c root]# pwd
/root
[root@f24280d7464c root]# hostname
f24280d7464c
[root@f24280d7464c root]# exit
exit
$ docker ps 
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

We combined the -i and -t options as -it while running docker run. Thanks to the –it option of docker run, we connected to the container, and we were able to use a terminal in this case.

We were in the /root directory. The name of the container was f24280d7464c this time. Finally, after exiting from the container, the output of docker ps showed that the container was stopped.

2.5. Running in the Detached Mode

It’s also possible to run the container in the detached mode. In this case, docker run starts the container in the background. We use the -d option to run the container in the detached mode:

$ docker run --rm –dt image1:6.0 /bin/bash
2b5e4ef1e6ef991fda69c60f7fa494a9370161c35cceae4b61ec3f939b2f7e7c
$ echo $?
0
$ docker ps 
CONTAINER ID   IMAGE        COMMAND       CREATED         STATUS         PORTS   NAMES
2b5e4ef1e6ef   image1:6.0   "/bin/bash"   9 seconds ago   Up 8 seconds           determined_chandrasekhar

In this case, we combined the -d option with the -t option as –dt. The container ID was printed when we ran the container using docker run. Running the container was successful since the exit status was 0. When we listed the running containers using docker ps, we saw that it was running.

We can connect to the running container using the docker exec command:

$ docker exec –it 2b5e4ef1e6ef /bin/bash
[root@2b5e4ef1e6ef root]# pwd
/root 
[root@2b5e4ef1e6ef root]# hostname
2b5e4ef1e6ef
[root@2b5e4ef1e6ef root]# exit
exit
$ docker ps
CONTAINER ID   IMAGE        COMMAND       CREATED          STATUS          PORTS   NAMES
2b5e4ef1e6ef   image1:6.0   "/bin/bash"   15 minutes ago   Up 15 minutes           determined_chandrasekhar

We passed the initial part of the container ID, 2b5e4ef1e6ef, to docker run for specifying the container. It’s also possible to pass the container name instead of the container ID. We also passed /bin/bash as the command to run in the container. The meaning of -it is the same as before.

After running docker exec, we connected to the container. We checked the current working directory and the hostname using the pwd and hostname commands. Then, we exited from the container using exit.

Finally, we checked whether the container was still running using docker ps, and we saw that it was.

We can stop the running container using the docker stop command. We can either pass the container ID or the container name. Let’s use the container name this time to stop it:

$ docker stop determined_chandrasekhar
determined_chandrasekhar
$ docker ps –a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Therefore, we could stop the container using docker stop.

2.6. Assigning a Hostname

In the examples we’ve seen so far, Docker assigned the hostname and the container name automatically. They were the same. However, we can specify the hostname using the -h option:

$ docker run --rm –it –h my_host image1:6.0 /bin/bash
[root@my_host root]# hostname
my_host
[root@my_host root]# exit
exit
$ docker ps 
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

The -h my_host part of docker run specified the hostname as my_host. Running hostname in the container returned my_host, as expected.

2.7. Assigning Container Name

We can specify the container name using the –name option:

$ docker run --rm –dt --name my_container image1:6.0 /bin/bash
9844f94f8e16625f6f54f55c8e63d808ff46367d21385d2c8813f1aa80b603be
$ docker ps 
CONTAINER ID   IMAGE        COMMAND       CREATED         STATUS         PORTS   NAMES
9844f94f8e16   image1:6.0   "/bin/bash"   5 seconds ago   Up 4 seconds           my_container

We specified the name of the container as my_container using –name my_container. The NAMES column in the output of docker ps showed that the container name is my_container.

Let’s stop the running container using the name we’ve assigned:

$ docker stop my_container
my_container
$ docker ps –a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

3. Using docker-compose

Running docker run from the command line might be cumbersome if the parameters passed to it are long. The parameters can be lengthy if we define volumes, ports, networks, etc. docker run also allows running one container at a time.

However, docker-compose can read the run-time configuration from a YAML file. It’s also possible to specify multiple containers in the YAML file.

We’ll use the following YAML file, example.yaml, for running two containers:

version: ‘3’

services:
   service1:
     image: image1:6.0
     container_name: container_1
     hostname: host1
     entrypoint: /bin/bash –c /root/infinite_script.sh 
   
   service2:
     image: image1:6.0
     container_name: container_2
     hostname: host2
     entrypoint: /bin/bash –c /root/infinite_script.sh 

We defined the containers in the services section of example.yaml. The service1 section defines the first container, and the service2 section defines the second. The image key defines the Docker image to be used by the containers. Both containers use the same image, image1:6.0.

The container_name key specifies the container name. The hostname key, on the other hand, specifies the hostname. The container names are container_1 and container_2. Similarly, the hostnames are host1 and host2.

Both containers run the script /root/infinite_script.sh within the container when we run the containers. This is specified using the entrypoint key. The script never ends, so the containers don’t exit immediately:

#! /bin/bash

tail –f /dev/null

Now, let’s start the containers using docker-compose:

$ docker-compose –f example.yaml up –d
Creating container_2 ... done
Creating container_1 ... done

We seem to start both containers successfully. The -f option of docker-compose specifies the YAML file. It’s optional. If we don’t specify it, Docker looks for a compose.yaml or docker-compose.yaml file. We passed example.yaml as the compose file using -f example.yaml.

The child command up of docker-compose starts the container. The -d option starts the container in the detached mode as before.

Let’s check the running containers:

$ docker ps
CONTAINER ID   IMAGE        COMMAND                    CREATED         STATUS         PORTS   NAMES
2c506f0e5ab1   image1:6.0   "/bin/bash –c /root/..."   2 minutes ago   Up 2 minutes           container_1
ae10ee7bf838   image1:6.0   "/bin/bash –c /root/..."   2 minutes ago   Up 2 minutes           container_2

Hence, both containers are up and running. We can stop the containers again using docker-compose using its child command down:

$ docker-compose –f example.yaml down
Stopping container_1 ... done
Stopping container_2 ... done
Removing container_1 ... done
Removing container_2 ... done

Therefore, we were able to start and stop multiple containers at the same time using docker-compose.

4. Using docker compose

A command that has been added to Docker recently is the docker compose. docker compose is different from docker-compose. It continues to support most of the commands and flags of docker-compose. It’ll replace docker-compose eventually. The docker-compose-plugin package must be installed to use docker compose.

The usage of docker compose is like docker-compose:

$ docker compose –f example.yaml up –d
Container container_2  Created
Container container_1  Created

Stopping the containers using docker compose is same as with docker-compose.

5. Conclusion

In this article, we discussed different methods for running a container using a Docker image.

First, we used docker run. We discussed its several options.

Then, we discussed docker-compose. We could run multiple containers at the same time using a YAML compose file.

Finally, we discussed the recent docker compose command for running a container. We saw that its usage is similar to docker-compose.