Docker

Docker Exec Command – How to Use It, Tips & Examples

Docker Exec Command

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:

  1. What is Docker exec?
  2. When to use Docker exec?
  3. How to use Docker exec command?
  4. Tips for using Docker exec
  5. Docker exec common errors
  6. Docker run vs Docker exec
  7. Docker attach vs Docker exec

What is Docker exec?

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>

Your <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 PATH.

Check out other Docker commands in the Docker CLI cheat sheet.

When to use Docker exec?

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

Here are a few more situations where you could use docker exec:

  • 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 exec to start it.
  • Run a one-off task in a container: docker exec also 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 exec allows 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 exec lets you investigate these situations by running commands like curl and wget to test which network endpoints the container can reach.

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

How to use Docker exec command?

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
752e081c8ebf6abdb7b3f4832d159a4cdc80ad7cd1033d139d80e737883d46ba

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 /
bin
boot
dev
...

The docker exec syntax means “run the ls / command in the container called demo“.

The output from the command that’s run in the container is displayed in your terminal.

Interactive commands

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:

  • -i (--interactive): Attaches your terminal’s standard input (STDIN) stream to the container, allowing it to receive input.
  • -t (--tty): Allocates a pseudo-TTY terminal to the session.

Then you should use the shell’s name (such as sh or bash) as your docker exec command:

$ docker exec -it demo bash
root@752e081c8ebf:/# 

Now you have a shell running inside your container, ready to run additional commands:

root@752e081c8ebf:/# ls
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 -d (--detach) flag:

$ docker exec -d demo /my-process

The 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 key=value format.
  • --env-file: Injects all the key=value environment 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
...
key=value
foo=bar

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 docker run.

You can run your command as a different user by setting the -u (--user) flag. This supports user_name:group_name and 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

Tips for using Docker exec

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

Each 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

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

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

  • Incorrect: docker exec demo bash -it
  • Correct: 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

Docker exec common errors

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 docker run.

2. Error response from daemon: Container is not running

This error occurs when you try to run a command in a stopped container. Use docker start 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.

Docker run vs Docker exec

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.

Docker attach vs Docker exec

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.

Key points

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.

Start free trial