Contents

Docker exec tutorial: Run commands in a running container

docker exec runs a command in a running container. It's most often used to enter a container and investigate a problem. For the full debugging workflow, see View logs and debug.

Syntax

docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
docker exec -it web sh        # Enter the container's shell
docker exec web nginx -t      # Run a command and get its output

Options

docker exec doesn't have many options. Here are all the options listed by docker exec --help:

OptionDescription
-i, --interactiveKeep standard input open so you can enter input
-t, --ttyAllocate a terminal. Use with -i for interactive sessions: -it
-u, --user USER[:GROUP]Run as the specified user (name or UID)
-w, --workdir PATHRun in the specified directory inside the container
-e, --env NAME=VALUESet an environment variable for this command
--env-file FILERead environment variables from a file
-d, --detachRun in the background and return immediately
--privilegedGive this command extra privileges (for debugging; don't use it routinely)
--detach-keysChange the key sequence for detaching (default: Ctrl+P, Ctrl+Q)

The examples below all run against an nginx container named web, which was started with the environment variable APP_MODE=demo:

docker run -d --name web -e APP_MODE=demo nginx:1.30-alpine

Run a command

$ docker exec web nginx -v
nginx version: nginx/1.30.5

$ docker exec web sh -c "ls /etc/nginx/conf.d && echo \$APP_MODE"
default.conf
demo
  • The first command runs nginx -v in the container and prints the result directly.
  • To use &&, pipes, or variables, pass the command to the container's shell with sh -c "...". The \ in \$APP_MODE prevents the host shell from expanding the variable first; demo is the value inside the container.

Enter a container interactively

docker exec -it web sh

After you enter, the prompt changes to / #. You can work as you would in a regular Linux environment. Enter exit to leave; the container keeps running. If the image includes bash, you can use bash instead.

-u, -w, and -e

$ docker exec -u nginx web id
uid=101(nginx) gid=101(nginx) groups=101(nginx)

$ docker exec -w /usr/share/nginx/html web ls
50x.html
index.html

$ docker exec -e GREETING=hi web sh -c "echo \$GREETING"
hi
  • -u nginx: Run as the nginx user (the container defaults to root). This is useful for checking file permission problems.
  • -w /usr/share/nginx/html: Run in the specified directory, as if you had run cd first.
  • -e GREETING=hi: Set an environment variable for this command only. It doesn't change the container itself.

-d: Run in the background

$ docker exec -d web sh -c "sleep 2; touch /tmp/done"

$ docker exec web ls /tmp
done

-d runs the command in the background and returns immediately. Check after 2 seconds, and /tmp/done has been created. This is useful for starting work when you don't need to wait for the result.

The container isn't running

$ docker stop web
web

$ docker exec web ls
Error response from daemon: container 1ec4fdc5c592b09b64e8f28869c37f89ab17163f88bfcb09e82815a44b0e1164 is not running

docker exec only works with a running container. Start a stopped container with docker start. If the container exits as soon as it starts, you can't use exec to enter it. Check docker logs instead, or start a new container for inspection with docker run --rm -it --entrypoint sh IMAGE.

Exercises

Exercise: Use one command to list the files in /etc/nginx in the web container as the nginx user.

Answer
docker exec -u nginx -w /etc/nginx web ls

FAQ

What's the difference between docker exec and docker run?

docker run uses an image to **create a new container**; docker exec runs another process in a **container that's already running**. When exec finishes, it doesn't affect the container itself.

Why does docker exec -it container bash return executable file not found?

The container doesn't have bash. For example, Alpine-based images only include sh. Use docker exec -it container sh instead.

Do files I modify in a container remain after I rebuild the container?

No. Changes made with exec are in the container's writable layer, and disappear when you delete the container. Put changes you need to keep in a Dockerfile or in a Volume.

Updated October 14, 2026