19.2.5 Exec CLI Command
A focused guide to Exec CLI Command, connecting core concepts with practical Docker and container operations.
docker exec runs a new command inside an already-running container. Unlike docker run, which creates a new container from an image, docker exec injects a new process into an existing, running container. The new process shares the container's namespaces — including its filesystem, network, PID tree, and environment — but it is independent of the container's primary process (PID 1). The container is not restarted, paused, or otherwise affected by the exec operation.
Basic Syntax
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
The container must be in the running state. docker exec cannot be used on stopped, paused, or exited containers.
Running a Simple Command
docker exec my-container ls /app
This executes ls /app inside my-container and prints the output to the current terminal. The container continues running its primary process undisturbed.
Opening an Interactive Shell
The most common use of docker exec is opening an interactive shell session inside a running container:
docker exec -it my-container bash
Or with sh if bash is not available:
docker exec -it my-container sh
The -i flag keeps stdin open. The -t flag allocates a pseudo-TTY. Together, they enable a fully interactive shell session. Exiting the shell (via exit or Ctrl+D) terminates only the exec'd process — the container's primary process continues running.
Flags and Options
| Flag | Description |
|---|---|
-i, --interactive | Keep stdin open even if not attached |
-t, --tty | Allocate a pseudo-TTY |
-d, --detach | Run the command in the background (detached mode) |
-e, --env | Set environment variables for the exec'd process |
--env-file | Read environment variables from a file |
-u, --user | Run as a specific user or UID |
-w, --workdir | Set the working directory for the exec'd command |
--privileged | Give extended privileges to the exec'd process |
Running as a Specific User
By default, the exec'd process runs as the user defined in the image. The -u flag overrides this:
docker exec -u root my-container whoami
docker exec -u 1001 my-container id
docker exec -u appuser:appgroup my-container bash
This is useful for running administrative commands (as root) on a container that normally runs as a non-root user.
Running a Command in a Specific Directory
docker exec -w /app my-container pwd
The process starts with /app as its current working directory.
Setting Environment Variables for the Exec Session
docker exec -e DEBUG=true my-container ./run-debug.sh
Environment variables set with -e are visible only to the exec'd process, not to the container's primary process or other processes.
Detached Execution
The -d flag runs the command in the background without keeping the terminal attached:
docker exec -d my-container ./run-background-task.sh
The command returns immediately with no output. The background process runs inside the container without interaction.
Practical Use Cases
Inspect the running container's filesystem
docker exec -it my-container bash
# Inside:
ls /app
cat /app/config.yaml
find /var -name "*.log"
Check environment variables
docker exec my-container env
Run a database query against a PostgreSQL container
docker exec -it postgres-container psql -U postgres -d mydb -c "SELECT COUNT(*) FROM users;"
Connect to Redis CLI
docker exec -it redis-container redis-cli
Check network connectivity from inside the container
docker exec my-container curl -s http://database:5432
docker exec my-container ping -c 3 database
Inspect a running process inside the container
docker exec my-container ps aux
docker exec my-container cat /proc/1/status
How docker exec Works Internally
When docker exec is invoked, the Docker daemon uses the kernel's namespace-joining capability to create a new process that enters the target container's existing namespaces (PID, network, mount, IPC, UTS). The new process is effectively inside the container's environment but was created from outside it.
The exec'd process:
- Sees the same filesystem as other processes in the container.
- Has the same network interfaces and routes.
- Runs in the same PID namespace (and can see other processes in the container).
- Inherits the container's hostname.
- Has its own separate stdin/stdout/stderr connected to the caller.
The exec'd process does not affect the container's lifecycle. When the exec'd process exits, the container continues running.
Limitations
docker execrequires the container to be running. It cannot exec into stopped, created, or paused containers.- Pausing a container first and then trying to exec will fail.
- If the container's primary process exits while an exec session is active, the container transitions to exited, and the exec'd process is killed when the container's namespaces are torn down.
docker execis a privileged operation — it requires access to the Docker socket.