Usually, you want Docker applications to be fully contained, but sometimes for development or automation purposes it’s useful to be able to work with Docker containers as if there were Linux VMs. Docker provides tools for running commands and even entire shells inside containers.
Running Commands In Containers
To run a command in a container, you’ll needs its container ID, unless you’ve set up a specific name for that container. This is a long hex string which you can find from the Docker process listing:
Then, you can use the
exec -it command to run inside the container. For example, viewing the output of a log file:
docker exec -it containerID tail /var/log/nginx/access.log
You can also run scripts inside containers:
docker exec -it containerID script.sh
-it flags are for “interactive mode” and TTY respectively, and are used almost all the time. There are a few other flags you can use:
-wchanges the current directory before the command.
-d, runs the command in the background.
-e, sets environment variables before running.
--env-filedoes the same, but is more secure for handling secrets.
--privilegedruns the command with extended permissions.
--userruns as a different user
Of course, this only works on a running container. If you wanted to pause a container to do maintenance, you’ll either need to deploy updates through a new image version, or do changes to volume mounted data from the host OS.
SSHing Into a Container
You aren’t limited to simple commands, you can actually open a shell by running
/bin/bash as the command. You might be limited in the tools available—most containers feature a fairly barebones Linux install—but it makes running many commands a lot easier.
docker exec -it containerID /bin/bash
This is simply a shell acccessible from the host, which works well in most case. But, if you want, you can set up your containers to be completely available over SSH like a VPS. You can read more about setting that up in our guide to running an SSH service in a Docker container.
RELATED: How to SSH Into a Docker Container
Copying Files To And From Containers
Running commands with
exec -it works, but there’s still a layer between the host and container that prevents easy scripting. For one, while it’s easy to send commands to a container, it’s harder to get output out from the filesystem.
While you can pipe the STDOUT of
exec -it to other services on the host OS, you can also copy files to and from the container’s filesystem. For example, pulling a log file out and pasting it on the host:
docker cp container:/var/log/nginx/example.log example.log
Or pulling out entire directories:
docker cp nginx:/etc/nginx/ nginxconfig/
If you’re regularly doing this though, you may want to consider using a bind or volume mount to make the data directly accessible from the host.