Docker Exec: Your Goto Command for Running Commands in Docker

Anthony Metcalf

Read more posts by this author.


Have you ever needed to see what’s going on inside a Docker container? Containers are intended to be idempotent: If there is a problem, redeploy a new container. Often life isn’t that simple. You need to run commands in the container to identify the issue. This is where the docker exec command can help.

This article will teach you how to run commands on a running Docker container using the docker exec command.

Prerequisites

To follow along with the examples in this article, you will need to adhere to the following.

  • Any recent version of the Docker Desktop will work on Windows, Linux, or macOS. This tutorial uses v3.1.0 running on Windows 10.

Starting an NGINX Container

Docker exec runs commands in containers. But, to do that, you must first have a container to run those commands in. Let’s start by downloading a Docker image and creating a demo container.

  1. Create a new directory, this tutorial uses C:\gitrepos\test, to hold the files used for the container.

2. Create a file, named dockerfile (no extension), containing the following code. The Dockerfile defines the steps necessary to create a container.

FROM nginx:alpine
 COPY index.html /usr/share/nginx/html/index.html

3. Next, create a file, in the same directory, named index.html which contains the following code. This is an HTML file that, when the container is started, will display a Hello World message.

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <meta http-equiv="X-UA-Compatible" content="ie=edge"> 
    <title>Hello World - Nginx Docker</title> 
    <style> 
       h1{ font-weight:lighter; font-family: Arial, Helvetica, sans-serif; 
       } 
    </style> 
    </head> 
    <body> 
       <h1> 
          Hello World 
       </h1> 

    </body> 
    </html>

4. Now create the Nginx Docker container. Since the Dockerfile is in the current working directory, specify . to let the Docker engine know to look there. Also, be sure to tag the container with my-ngnix using the t parameter to ensure an easier reference in the future.

docker build -t my-nginx .
Creating a Docker container with the build command.
Creating a Docker container with the build command.

5. Now that the container is built, start the container with the Docker run command.

# rm - Informs Docker to delete the container after it has stopped 
# d - Return control of the command-line after the command has been executed 
# p - Map the internal container port 80 to an external port 80 docker run --rm -d -p 80:80 my-nginx
Start the container with the Docker run command.
Start the container with the Docker run command.

6. Finally, open your web browser and navigate to http://localhost/ to see the following.

Output of the running NGINX container.
Output of the running NGINX container.

Running Commands with Docker Exec

When running commands in a Docker container, you may need to run a command interactively. Running commands interactively means typing in a command, getting feedback, typing in another command, etc. Interactive commands take over your session and prevent you from doing anything else.

But what if you already know the commands to send to the container ahead of time and want to run commands in the background? In that case, you can run non-interactive commands. Non-interactive commands allow you to send a command to Docker and instantly return control of the console.

Locating the Container Name and ID

Now that you have the container built, you can execute commands inside of the container. Before running a command, locate either the NGINX container’s name or ID. Either the name or ID will work in Docker commands. With that in mind, remembering the ID may be more challenging than the name!

To display any running container information, run the Docker ps command to output the following information.

docker ps
Displaying running Docker containers.
Displaying running Docker containers.

Copy either the unique ID, e17e4b6be01a, or the randomly generated name mystifying_chandrasekhar to your clipboard for later use.

Running a Non-Interactive Command with Docker Exec

As an example of running a non-interactive command, copy and run the below command to return a list of files in the /var/log directory with the ls -l command. Pass everything after the container name, mystifying_chandrasekhar, to the Docker exec command.

docker exec mystifying_chandrasekhar ls -l /var/log
Executing a directory listing within the NGINX container.
Executing a directory listing within the NGINX container.

Avoiding Console Output with Docker Commands

By instantly returning shell control to the user, large operations avoid tying the console up. Forgo console output with the detached d option. The command below creates the file /tmp/execWorks via the touch command within the container and does not display any output on the console.

docker exec -d mystifying_chandrasekhar touch /tmp/execWorks

Executing Interactive Commands with Docker Exec

Up to this point, you’ve learned how to run non-interactive commands in a Docker container with docker exec. But, you might face a time when you must troubleshoot a container, for example, when you need to issue commands to the container interactively. In that case, you need to run commands interactively.

Running commands interactively with docker exec requires two options, i and t. The i option keeps STDIN open, allowing commands to be sent to the container, and the t option allocates a pseudo-TTY (PTY), a communication channel, to type commands in.

Copy and paste the following command to open an interactive command prompt to the running Docker container with the Bourne (sh) shell, as indicated by the prompt change to / #.

docker exec -it mystifying_chandrasekhar sh
Running an interactive Docker shell.
Running an interactive Docker shell.

Once in the shell, now run the commands below to demonstrate listing files from within the container. Finally, running the exit command to leave the interactive shell.

ls -l /var/log
exit
Open an interactive command prompt to the container.
Open an interactive command prompt to the container.

To open an interactive prompt in a specific directory, pass the path to the w option telling Docker to start the shell in a specified directory.

Passing Environmental Variables to a Running Container

Many programs use environment variables to set configurations at startup. For example, most Java applications require the JAVA_HOME environmental variable to set to the Java path.

You can pass environment variables to a session using the e option. For example, perhaps you need to populate an environment variables called MYVAR into a running container. To do that, use the e option and provide the key/value pair of MYVAR="<some value>" as shown below.

docker exec -it -e MYVAR="hello" mystifying_chandrasekhar sh
echo $MYVAR
Pass environment variables
Pass environment variables

Passing Environment Variables With a File

If you have many environmental variables or a shared configuration, storing those variables in a file may be easier. Pass the file via a relative or absolute path to Docker with the --env-file option. This technique is often used to provide secure credentials to a container. Be sure never to commit credentials to version control!

Create a text file named env-vars.txt with the environmental variables to pass and their values. This file can be called anything you like and does not need the .txt file extension.

Text file with environmental variables defined.
Text file with environmental variables defined.

Pass the environmental variables to Docker with the env-file option. Verify that the variables are available with the echo command as shown in the below screenshot.

# Pass the env-vars.txt file and open an interactive prompt
docker exec -it --env-file env-vars.txt mystifying_chandrasekhar sh
# Verify that the environmental variables are available in the Docker container
echo $MYVAR
echo $FOO
echo $SOMETHING
Passing a environmental variables file to Docker and verifying the environment variables exist in the container.
Passing a environmental variables file to Docker and verifying the environment variables exist in the container.

Interacting with a Running Container as a Different User

In production, applications often run as a specific user to restrict their access. If you’re running applications as a specific user in production, you should also do so while testing commands.

In this example, the Docker container is run as the nginx user. Pass the user to the w option to tell Docker to start the container as the nginx account. The whoami command, run from within the container, confirms that the nginx user is indeed used.

docker exec -it -u nginx mystifying_chandrasekhar sh
whoami
Running the container as the nginx user.
Running the container as the nginx user.

Next Steps

You have learned how to execute commands within a running container using the docker exec command. Utilizing the exec command to enter and interrogate running containers, you have a powerful new tool in your arsenal to troubleshoot Docker containers.

Now try to take what you have learned a step further and use Git version control to pull a static website into the container, rather than copying a single file. If Git is new to you, then the article A Beginner’s Guide to Visual Studio Code and Git is a great place to start.

Subscribe to Stay in Touch

Never miss out on your favorite ATA posts and our latest announcements!

Looks like you're offline!