✦ For everyone, free.

Practical knowledge for real and everyday life

Home

19.2.5.2 Exec Shell Session

A focused guide to Exec Shell Session, connecting core concepts with practical Docker and container operations.

An exec shell session is an interactive shell opened inside a running Docker container using docker exec -it. It provides direct access to the container's filesystem, environment, installed tools, and running processes, making it the primary method for debugging, inspecting, and administering containers in real time without stopping or restarting them.

Opening a Shell Session

The canonical command for opening a bash shell inside a running container:

docker exec -it my-container bash

If the container image does not include bash (common in minimal and Alpine-based images), use sh instead:

docker exec -it my-container sh

After running this command, the terminal prompt changes to reflect the shell inside the container:

root@3a4b5c6d7e8f:/app#

The user, container ID, and current working directory are shown. Everything typed here executes inside the container.

Exiting the Shell Session

Type exit or press Ctrl+D to end the shell session. Only the exec'd shell process exits — the container's primary process (PID 1) continues running unaffected. The container remains in the running state.

Why -i and -t Are Both Needed

-i keeps stdin open, allowing input to be typed into the shell. Without -i, the shell closes stdin immediately and there is nothing to type.

-t allocates a pseudo-TTY, which gives the shell a proper terminal interface: command-line editing (arrow keys, backspace, history), ANSI color support, and proper prompt display. Without -t, the shell works but behaves strangely — no prompt is shown, line editing does not work, and interactive programs like editors or package managers may fail.

The Shell Environment

The shell session inherits:

  • The container's filesystem (all files, directories, and mounted volumes).
  • The container's environment variables (set when the container was started).
  • The container's network interfaces and DNS configuration.
  • The container's hostname.

It does NOT inherit custom variables set with docker exec -e unless explicitly added to the session.

Check the environment inside the shell:

env
echo $DATABASE_URL
hostname
cat /etc/resolv.conf

Navigating the Filesystem

ls /app
cd /app
cat config.yaml
find / -name "*.log" 2>/dev/null
du -sh /var/log

Checking Running Processes

ps aux

This shows all processes inside the container's PID namespace, including the container's primary process (PID 1) and any other processes started by it.

Network Diagnostics from Inside the Container

curl -s http://localhost:8080/health
curl -s http://database:5432
ping -c 3 db
nslookup database
cat /etc/hosts

Because the shell is inside the container's network namespace, it sees the container's own network stack. DNS names and IP addresses resolve as they would for the container's application process — not as the host would see them.

Installing Packages Temporarily

For containers based on Debian or Ubuntu:

apt-get update && apt-get install -y curl jq

For Alpine-based containers:

apk add --no-cache curl jq

Packages installed this way exist only in the container's writable layer. They disappear when the container is removed. For debugging purposes, this is acceptable. For production, these packages should be added to the Dockerfile instead.

Running Database CLI Tools Inside the Container

For PostgreSQL containers:

docker exec -it postgres-container bash
# Inside:
psql -U postgres -d mydb

Or directly:

docker exec -it postgres-container psql -U postgres -d mydb

For MySQL containers:

docker exec -it mysql-container bash
# Inside:
mysql -u root -p

Examining Application Logs Written to Files

If the application writes to log files on the filesystem rather than stdout:

docker exec -it my-container bash
# Inside:
tail -f /app/logs/app.log
cat /app/logs/error.log | grep -i "exception"

Running Exec as Root on a Non-Root Container

If the container runs as a non-root user but administrative access is needed:

docker exec -it -u root my-container bash

This opens a root shell regardless of the container's configured user.

Using exec for Scripted Operations

Shell sessions are interactive, but exec can also run non-interactive scripts:

docker exec my-container bash -c "ls /app && cat /app/version.txt"

The bash -c form evaluates the string as shell commands, enabling pipelines, variable expansion, and other shell features in a single exec call without opening an interactive session.

Session Limitations

  • The shell session requires the container to be running. If the primary process exits during the shell session, the container transitions to exited and the shell session is terminated.
  • Changes made inside the shell session (file modifications, installed packages) persist in the container's writable layer until the container is removed. They do not persist to the image.
  • Multiple exec sessions can be open simultaneously on the same container — each is independent.