Docker
Command Line
Container Management
DevOps
Software Development

How do I run a command on an already existing Docker container?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

If a container already exists and is running, the normal way to execute another command inside it is docker exec. That command starts a new process in the existing container without replacing the container's main process, which makes it the standard tool for debugging, maintenance, and one-off admin tasks.

Running a One-Off Command with docker exec

The basic syntax is straightforward:

bash
docker exec container_name command

For example, if you want to inspect files or print environment variables:

bash
docker exec web ls /app
docker exec web env
docker exec web python manage.py migrate

Each call launches a separate process inside the already-running container. This is different from editing the container definition or rebuilding the image. It is also different from changing the container's startup command. docker exec is for extra processes after the container is already alive.

Opening an Interactive Shell

When you need to troubleshoot manually, open a shell instead of running a single command. Add -i and -t, usually combined as -it.

bash
docker exec -it web sh

If the image contains bash, you can use it:

bash
docker exec -it web bash

Many slim images do not ship with bash, so sh is the safer default. The -i flag keeps standard input open, and -t allocates a terminal. Without them, interactive shells usually behave badly or exit immediately.

Make Sure the Container Is Running

docker exec works only on running containers. If the container exists but is stopped, Docker cannot start a new process inside it.

bash
docker ps -a

If the container is stopped, start it first:

bash
docker start web
docker exec -it web sh

If it stops again right away, inspect the logs instead of retrying exec.

bash
docker logs --tail 200 web

That usually reveals whether the main application process is crashing, missing configuration, or exiting on purpose.

Useful Flags for Real Work

docker exec has a few options that matter in day-to-day debugging.

Run as a specific user:

bash
docker exec -u 1000:1000 web id

Change the working directory:

bash
docker exec -w /app web pwd

Pass environment variables to the new process:

bash
docker exec -e DEBUG=1 web sh -c 'echo "$DEBUG"'

Wrap compound shell logic in sh -c:

bash
docker exec web sh -c 'test -f /app/config.yaml && echo present || echo missing'

These flags are especially useful when you are checking permissions, testing a script in the app directory, or reproducing behavior under a specific runtime setting.

docker exec Versus docker attach

People often confuse exec with attach. They are related, but they are not interchangeable.

bash
docker attach web

attach connects your terminal to the container's main process. exec starts a brand-new process inside the container. For most maintenance work, exec is safer and more practical because it does not depend on how the main process handles input and output.

If you just want a shell, a migration command, or a quick filesystem inspection, use exec. Save attach for cases where you intentionally need to interact with the original process.

Compose Users Can Use docker compose exec

If the container belongs to a Compose project, the service-oriented command can be more convenient.

bash
docker compose exec web python manage.py migrate
docker compose exec web sh

This targets the service name instead of requiring you to remember the generated container name. It also fits better into teams that already manage local environments through Compose.

Treat Manual Container Changes as Temporary

You can edit files or install packages after entering a container, but those changes usually live only in that container's writable layer. If the container is recreated, the changes disappear.

That makes docker exec good for diagnosis and short-lived experiments, but not for permanent fixes. If a fix matters, put it in one of these places instead:

  • the Dockerfile
  • the entrypoint or startup script
  • the mounted configuration or data
  • the Compose or deployment manifest

The operational rule is simple: debug with exec, persist with configuration.

Common Pitfalls

The most common mistake is trying docker exec on a stopped container. Another is assuming every image includes bash, which is not true for Alpine-based and other minimal images. Developers also make changes manually inside the container and then get confused when those changes disappear after recreation. Finally, attach is often used by mistake when what the user really wants is a new shell or command process.

Summary

  • Use docker exec to run an extra process inside an already-running container.
  • Add -it when you need an interactive shell.
  • Start the container first if it is stopped.
  • Prefer exec over attach for most debugging and maintenance tasks.
  • Treat manual in-container changes as temporary unless you move them into the image or deployment config.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.