Sooner or later you need to look inside a container: check a config file, run a database command or see why the app cannot reach something. docker exec runs a command in a container that is already running, without restarting it. This guide covers interactive shells, one-off commands, users, and copying files with docker cp.
Before you start
- A Linux VPS with Docker Engine installed. See Install Docker and Docker Compose.
- A running container.
docker execdoes not work on stopped containers. - The container name or ID from
docker ps.
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'Open an interactive shell
docker exec -it web bash-ikeeps standard input open so you can type.-tgives you a proper terminal, so the prompt and line editing work.
Many small images, such as those based on Alpine or BusyBox, do not include bash. Use sh instead:
docker exec -it web shType exit or press Ctrl + D to leave. The container keeps running.
Note: Some hardened images, often called distroless, contain no shell at all. docker exec then fails with executable file not found. Use docker cp to read files, or start a debug container that shares the target's network, as shown below.
Run a one-off command
Leave out -it when you only need the output:
docker exec web cat /etc/nginx/conf.d/default.conf
docker exec web nginx -t
docker exec db psql -U postgres -c 'select version();'Use -it again for commands that need a terminal, such as an interactive database client:
docker exec -it db psql -U postgresTo use shell features like pipes or * inside the container, wrap the command in sh -c:
docker exec web sh -c 'ls /var/log/nginx/*.log | wc -l'Without sh -c, the pipe would run on the host instead.
Run as root or as another user
docker exec runs as the image's default user. Many images run as a non-root user for safety, so commands such as package installs fail. Run as root for a moment:
docker exec -it -u root app shOr run as a specific user or numeric ID:
docker exec -u www-data app php artisan cache:clear
docker exec -u 1000:1000 app idWarning: Changes you make inside a container, such as installing a package or editing a file outside a volume, are lost when the container is recreated. Treat exec sessions as a place to inspect and test. Make permanent changes in the Dockerfile, the Compose file or a mounted volume.
Set the working directory and environment
docker exec -w /app -e DEBUG=1 app node scripts/check.js-w sets the directory the command starts in, and -e adds an environment variable for this command only.
Exec into a Compose service
From the project folder, you can use the service name instead of the container name:
docker compose exec app sh
docker compose exec db psql -U postgresdocker compose exec allocates a terminal by default, so -it is not needed. Add -T to disable it when running from a script or cron job.
Copy files with docker cp
docker cp copies between the host and a container. It works on stopped containers too.
Copy a file out of the container:
docker cp web:/etc/nginx/nginx.conf ./nginx.confCopy a file in:
docker cp ./nginx.conf web:/etc/nginx/nginx.conf
docker exec web nginx -s reloadCopy a whole folder out:
docker cp app:/app/logs ./app-logsFiles copied into a container end up owned by root. If the app runs as another user, check ownership with docker exec web ls -l /etc/nginx/ and fix it with docker exec -u root web chown if needed.
Debug a container that has no tools
To test networking from the point of view of a minimal container, start a throwaway container that shares its network:
docker run --rm -it --network container:app nicolaka/netshootInside it you have curl, dig, ss and other tools, and localhost is the app container's localhost. If you prefer not to pull a third-party image, busybox:stable offers wget and nslookup.
Check it works
Confirm you are inside the right container and as the right user:
docker exec web sh -c 'hostname; id; pwd'The hostname matches the container ID shown by docker ps, and id shows the user the command ran as.
Troubleshooting
Error response from daemon: container... is not running: start it first withdocker start NAME. If it stops again straight away, see Fix a Docker container that exits immediately.OCI runtime exec failed: exec: "bash": executable file not found: the image has no bash. Usesh, ordocker cpfor distroless images.the input device is not a TTY: you used-tfrom a script or cron job. Drop-t, or usedocker compose exec -T.Permission deniedinside the container: you are running as a non-root user. Add-u rootfor that command.
Next steps
- Find out why a container keeps stopping: Fix a Docker container that exits immediately.
- Make changes permanent in an image: Write a Dockerfile and build your first image.
