Introduction
Docker is a containerization tool for developers that allows them to create and manage portable, consistent Linux containers.
When developing or deploying containers, you’ll frequently need to inspect or debug a running container’s current state. Docker provides the docker exec command to run programmes in already running containers to this end.
In this tutorial we will learn about the docker exec command and how to use it to run commands and get an interactive shell in a running Docker container.
Prerequisites
This tutorial assumes you already have Docker installed and that your user has docker permissions. If you need to run docker as the root user, remember to prefix the commands in this tutorial with sudo.
Launching a Test Container
To use the docker exec command, you must have a Docker container running. Start a test container if you don’t already have one by using the docker run command:
This command launches a new Docker container based on the official alpine image. This is a well-known Linux container image that runs Alpine Linux, a lightweight and minimal Linux distribution.
The -d flag tells the container to disconnect from our terminal and run in the background. –name container-name will give the container the name container-name. You can enter any name you want here, or leave it blank to have Docker generate a unique name for the new container.
Following that is alpine, which specifies the image to be used for the container.
Finally, you should monitor “date >> /var/log/date.log”. This is the command we want to run in the container. watch repeats the specified command every 2 seconds by default. The monitor command executed in this case is date >> /var/log/date.log. date prints the current date and time as follows:
Sat Oct 01 11:32:09 UTC 2022
The >> /var/log/date.log section of the command redirects the output of date and appends it to the /var/log/date.log file. Every 2 seconds a new line is added to the file and after a few seconds it looks like this:
Output :
Sat Oct 01 11:35:10 UTC 2022
Sat Oct 01 11:35:12 UTC 2022
Sat Oct 01 11:35:14 UTC 2022
Sat Oct 01 11:35:16 UTC 2022
Sat Oct 01 11:35:18 UTC 2022
In the next step, we’ll learn how to find the Docker container name. This is useful if you already have a container you’re targeting but don’t know its name.
Finding a Docker Container's Name
The name (or container ID) of the container we want to work with must be provided to docker exec. Using the docker ps command, we can find this information:
This command displays a list of all Docker containers that are currently running on the server, as well as some high-level information about them:
Output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
76aded7112d4 alpine “watch ‘date >> /var…” 11 seconds agoUp 10 seconds container-name
This command displays a list of all Docker containers that are currently running on the server, as well as some high-level information about them:
The container ID and name are highlighted in this example. You can tell docker exec which container to use by using either.
You can rename your container using the docker rename command:
Following that, we’ll go over several examples of how to use docker exec to execute commands in a running Docker container.
Running an Interactive Shell in a Docker Container
Use docker exec with the -i and -t flags to start an interactive shell inside a Docker Container, for example, to explore the filesystem or debug running processes.
The -i flag keeps the container’s input open, and the -t flag creates a pseudo-terminal to which the shell can connect. These flags can be combined as follows:
This will launch the sh shell in the specified container, displaying a standard shell prompt. To return to the container, type exit and press ENTER:
If your container image includes a more advanced shell, such as bash, you could use bash instead of sh above.
Running a Non-interactive Command in a Docker Container
If you need to run a command inside a running Docker container but don’t want to interact with it, use the docker exec command without any flags:
This command runs tail /var/log/date.log for the container-name container and prints the results. By default, the tail command prints the last ten lines of a file. If you run the demo container we set up in the first section, you’ll see something like this:
Output :
Sat Oct 01 12:00:02 UTC 2022
Sat Oct 01 12:00:04 UTC 2022
Sat Oct 01 12:00:06 UTC 2022
Sat Oct 01 12:00:08 UTC 2022
Sat Oct 01 12:00:10 UTC 2022
Sat Oct 01 12:00:12 UTC 2022
Sat Oct 01 12:00:14 UTC 2022
Sat Oct 01 12:00:16 UTC 2022
Sat Oct 01 12:00:18 UTC 2022
Sat Oct 01 12:00:20 UTC 2022
This is essentially the same as opening an interactive shell for the Docker container (like in the previous step with docker exec -it container-name sh) and then running the tail /var/log/date.log command. However, instead of opening a shell, running the command, and then closing the shell, this command returns the same output in a single command and without opening a pseudo terminal.
Running Commands in an Alternate Directory in a Docker Container
To run the command in a specific directory in the container, use the –workdir flag to specify the directory.
This example command sets the /tmp directory as the working directory and runs the pwd command, which prints the current working directory.
/tmp
The pwd command has confirmed that the working directory is /tmp.
Running Commands as a Different User in a Docker Container
Add the –user flag to run the command as a different user inside the container.
The guest user will be used to perform the whoami command in the container. The whoami command displays the username of the current user
guest
The whoami command confirms that the current user of the container is guest.
Environment Variables in a Docker Container
Sometimes environment variables must be passed into a container together with the command to run. The -e option allows you to provide an environment variable:
This command changes the TEST environment variable to sammy and then executes the env command within the container. Following that, the env command displays all of the environment variables:
Output :
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=76aded7112d4
TEST=sammy
HOME=/root
The variable TEST is set to sammy.
To set several variables, use the -e flag numerous times:
You can use the —env-file flag to pass in a file containing environment variables.
To begin, create the file with a text editor. We’ll start a new file with nano here, but you can use whatever editor you prefer:
We’re using the filename .env since it’s a common convention for utilising these types of files to manage information outside of version control.
Put your KEY=value variables in the file, one per line, like this:
TEST=sammy
ENVIRONMENT=prod
Save and close the file. To save the file and exit nano, press CTRL+O, then ENTER to save, then CTRL+X to exit.
Run the docker exec command again, this time supplying the right filename after —env-file:
Output:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=76aded7112d4
TEST=sammy
ENVIRONMENT=prod
HOME=/root
The file’s two variables have been set.
Multiple files can be specified by using multiple —env-file flags. If the variables in the files overlap, the latest file listed in the command will take precedence over the prior files.
Common Errors
You may encounter the following errors while executing the docker exec command:
The No such container error indicates that the specified container does not exist and may be the result of a misspelt container name. Docker ps may be used to list all of your running containers and double-check their names.
This not running notification indicates that the container exists but is not running. Docker start container-name will start the container.
The Container is paused error describes the issue very clearly. Before continue, you must unpause the container with docker unpause container-name.
Conclusion
We learnt how to execute commands in a running Docker container, as well as various command line parameters accessible while doing so, in this article.