Docker exec is a useful way to debug container problems and perform one-off maintenance tasks. In this article, we’ll go in-depth on these scenarios and show how to use docker exec with common options. Let’s get started.
We will cover:
docker exec is a Docker CLI feature that runs a command inside a running container. It launches an additional process that’s independent of the main process running in the container.
You must identify the container by ID or name, then specify the command to invoke:
$ docker exec <container-id-or-name> <command>
<command> can be any command that exists in the container. To pass arguments or flags, simply write them after the command’s name:
$ docker exec <container-id-or-name> echo -n demo
The command you use must be a valid executable within the container’s filesystem. It will be interpreted relative to the container’s default working directory. You must specify the exact path to the command if it’s situated in a different directory that’s outside the container’s
Check out other Docker commands in the Docker CLI cheat sheet.
Docker containers usually run a single long-lived process, typically a server application. But sometimes, you might need to run another command inside a container. This is where
docker exec steps in.
One of the
docker exec‘s best use cases concerns debugging and troubleshooting container problems. The command allows you to easily inspect a container filesystem and make any changes you require, without having to launch a new container or refer to the source
Here are a few more situations where you could use
- Run maintenance commands: Some container images include additional utility commands to handle maintenance operations. For example, the official MySQL image bundles the mysqldump backup utility, but you’ll need to use
docker execto start it.
- Run a one-off task in a container:
docker execalso facilitates other types of one-off tasks, such as viewing log files that are stored within containers. You can also use the command in development scenarios, such as to apply changes to an application’s source code without having to rebuild its container image.
- Inspect a container’s filesystem:
docker execallows you to directly interact with the target container’s filesystem. You can learn how the image is assembled, identify what components are included, and adjust configuration files.
- Test container network connectivity: It’s not always obvious why a container is having network connectivity issues.
docker execlets you investigate these situations by running commands like
wgetto test which network endpoints the container can reach.
docker exec can be useful in these scenarios, it’s important to avoid relying on the command too often. It’s best reserved for debugging and troubleshooting problems when you’ve exhausted all other options.
Starting additional processes in a container risks breaking containerization principles, as containers should usually run one service each. Using
docker exec to apply “permanent” changes to a container—such as by installing extra packages—will introduce discrepancies compared to the Dockerfile, causing configuration drift. Therefore,
docker exec must be used with caution: starting another container that reuses the same volumes and networks is often a better choice for running maintenance commands, for example, as this won’t cause any side effects in your existing container’s configuration.
Now you’re aware of the use cases and pitfalls of
docker exec, let’s see how to actually use it to run commands in your own containers.
To begin with, you should create a new container to follow along with this guide. We’ll call our container
demo and refer to it by name in the following steps.
$ docker run -d --name demo nginx:latest
docker ps should now show that the container is up:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
752e081c8ebf nginx:latest "/docker-entrypoint.…" 32 seconds ago Up 30 seconds 80/tcp demo
The container is now running its default command, which in this case is a script that starts the NGINX web server.
Now you can use
docker exec to start another command in the container. The following example executes
ls / to list the contents of the container’s filesystem root:
$ docker exec demo ls /
docker exec syntax means “run the
ls / command in the container called
The output from the command that’s run in the container is displayed in your terminal.
docker exec can be used to launch an interactive shell session inside your container. For this to work correctly, two optional flags must be used:
--interactive): Attaches your terminal’s standard input (STDIN) stream to the container, allowing it to receive input.
--tty): Allocates a pseudo-TTY terminal to the session.
Then you should use the shell’s name (such as
bash) as your
docker exec command:
$ docker exec -it demo bash
Now you have a shell running inside your container, ready to run additional commands:
bin boot dev ...
You can end the session by running the
exit command inside the container’s shell.
Docker exec options
The Docker exec command supports a few other options too. Here’s how to use them.
1. Detach from the container command
docker exec automatically attaches your terminal to the command that’s run in the container. This lets you monitor the command’s output in your existing terminal session. However, if you’re running a time-consuming command or launching another background service, you might prefer to detach from it using the
$ docker exec -d demo /my-process
docker exec command will appear to complete immediately, but the process started in the container will keep running until it naturally exits.
2. Set environment variables
docker exec allows you to set additional environment variables inside the container that will apply when your command is run. Similarly to other Docker commands, two different flags are supported:
--env: Sets a specific environment variable in
--env-file: Injects all the
key=valueenvironment variable pairs found in a named file.
You can repeat each of these flags to set multiple variables.
This demo shows how the environment variables you define are successfully set inside the container:
$ docker exec --env key=value --env foo=bar demo env
3. Set the user
Container processes created by
docker exec run as the container’s default user. This is normally
root unless you changed it in your Dockerfile or when starting the container with
You can run your command as a different user by setting the
--user) flag. This supports
uid:gid syntax. The group portion is optional in both cases.
$ docker exec --user 1234:100 demo whoami
uid=1234 gid=100(users) groups=100(users)
Running all commands as a non-root user is a best practice to improve Docker security.
4. Change the container’s working drectory
You can change the effective working directory inside the container by setting the
--workdir flag. The path to your command’s executable will then be resolved relative to the specified directory instead of the container’s default working directory.
$ docker exec --workdir /app/bin demo demo-cli
Now you’ve learned the options for using
docker exec, here are a few tips and gotchas to ensure your commands run smoothly.
How to run multiple commands in a container with docker exec
docker exec invocation runs a single command in your container. Directly chaining commands, as in the following example, won’t produce the desired result:
$ docker exec demo echo "Hello" && ls
echo "Hello" command will run in the container, but the
&& will be interpreted by your system’s shell. As a result, the
ls command will run on your host, not in the container.
If you need to chain multiple commands together, you can repeat
$ docker exec demo echo "Hello" && docker exec demo echo ls
Alternatively, you can use
docker exec to launch a shell process in your container, then pass through your entire command chain as a quoted string:
$ docker exec demo bash -c "echo 'Hello' && ls"
Check your command syntax
The syntax of both your
docker exec command and the command you pass to your container must be error-free to ensure correct operation. Notably, the flags you pass to
docker exec must come before the container ID/name and your command. Otherwise, they’ll be interpreted as part of the command to run in the container.
docker exec demo bash -it
docker exec -it demo bash
Ensure your container is running
docker exec only works with containers that are actively running. You’ll see an error message similar to the following if you try to run a command in a a stopped or paused container:
Error response from daemon: Container is not running
To solve this problem, start or unpause the container (using the
docker start or
docker unpause command, respectively), then repeat the
docker exec command.
Use a non-root user
You should avoid running commands as root unless absolutely necessary. Otherwise, the command you run in the container could potentially perform sensitive actions on your host, if it’s been compromised or replaced with a malicious version. Setting the
--user flag to ensure your new process runs as a specific user helps to lower your risk.
$ docker exec --user 1000 demo ls
Here are four common
docker exec errors and how you can solve them.
1. Error: No such container
This means Docker couldn’t run your command because you’ve referenced an invalid container. You should check the container name for typos. If it’s correct, then make sure you’ve already started the container using
2. Error response from daemon: Container is not running
This error occurs when you try to run a command in a stopped container. Use
to restart the container, then repeat your
docker exec command.
3. Error response from daemon: Container is paused
This error is similar to the previous one but it happens when you interact with a paused container. You must
docker unpause the container, then repeat the
docker exec command.
4. OCI runtime exec failed: unable to start container process: executable file not found
An error message similar to this one means
docker exec failed to start the command you requested in the container. You should look for typos in the executable name you specified and check that it exists within the container’s filesystem.
A common source of confusion about
docker exec is how it differs from
docker run. These commands both ultimately run commands in containers, but they have different purposes and effects.
docker run creates a new container and optionally sets the initial command to run inside it. When no command is specified, then the default given by the container image’s Dockerfile will be used.
docker exec is used for running additional commands inside existing containers. The original command stays running and a new process is launched in the container.
Another related command to
docker exec is
docker attach. This attaches your terminal to a running container process, allowing you to monitor its output and provide input when required. It’s not possible to attach to commands that have already completed their execution and exited.
This article has explored
docker exec, a Docker CLI command that’s used to run new commands in existing containers. It’s useful for debugging, troubleshooting, and learning purposes; it also allows you to run one-off tasks inside containers, such as creating a backup using a utility provided by the container image.
It’s unlikely that you’ll use
docker exec often in production. Manual interactions with containers are best avoided to prevent consistency issues and maintain automation. However, understanding how to use the command will make it easier to diagnose problems with your containers.
We encourage you also to explore how Spacelift offers full flexibility when it comes to customizing your workflow. You have the possibility of bringing your own Docker image and using it as a runner to speed up the deployments that leverage third party tools. Spacelift’s official runner image can be found here.
The Most Flexible CI/CD Automation Tool
Spacelift is an alternative to using homegrown solutions on top of a generic CI. It helps overcome common state management issues and adds several must-have capabilities for infrastructure management.