Run Linux Commands Inside Containers With Docker Compose
There are two ways you can run Linux commands inside Docker containers: you use the Docker exec command to run it from outside the container or you enter the running container first and then run the command like you do it in a regular Linux terminal.
To run a Linux command on a Docker container immediately, without entering, you can use the docker exec
command like this:
docker exec container_name_or_ID bash -c "<linux command>"
Depending upon the type of shell available within the container, the command may differ on a case-by-case basis. It could be sh
instead of bash
too.
Similarly, you can enter a container's shell and run Linux commands in it.
docker exec container_name_or_ID bash
Not only Docker, but Docker Compose can also come in very handy, especially when you are running your web app services (which is the preferred way on production systems) specified according to their yml files, residing in respective directories.
Let me discuss it in detail.
Method 1: Direct container shell commands using Docker Compose
For beginners, the most commonly known way is first to cd into the service directory and then run the exec
command.
Let's say, for example, first you "cd" into the service directory:
avimanyu@iborg-desktop:~$ cd web-app-service
avimanyu@iborg-desktop:~/web-app-service$
At this stage, you can run the same exec
command (shown in the introductory example) using docker-compose
. Here's how:
avimanyu@iborg-desktop:~$ docker-compose exec web-app bash -c "<linux command>"
The advantage here, in this case, is that you do not need to check the corresponding container name (with docker ps
) relevant to the web app service you are running. You directly use the service name web-app
that was specified within the docker-compose.yml
file inside the service directory while it was configured.
But what if you do not want to cd into these web app service directories every time during maintenance/troubleshooting? Let's see how:
For example, the following command runs "docker-compose exec" from any PWD location for the intended webapp service, which otherwise would have to be executed by cding into the service's docker compose directory:
avimanyu@iborg-desktop:~$ docker-compose -f ~/web-app-service/docker-compose.yml exec web-app bash -c "<linux command>"
Through a single line, you can specify the location of the YML file as well as execute the command for the specific service. Isn't this interesting? So, not only exec
, you can run any of the various Docker Compose child commands of your preference, for any web app in this manner! This can be very helpful to escalate troubleshooting faster than usual.
Method 2. Indirect Container Shell Commands using Docker Compose
By indirect shell commands, I mean entering the container shell first before you enter the command inside it. That can be done using Docker Compose as well. Again, let's first "cd" into the service directory:
avimanyu@iborg-desktop:~$ cd service
avimanyu@iborg-desktop:~/service$
Once inside this PWD, you can enter the service's container shell:
avimanyu@iborg-desktop:~/service$ docker-compose exec web-app bash
root@019b69d74173:/app#
Now you can run the command you want inside the container. But let us look at it again on how to do it straightaway from any location(PWD):
avimanyu@iborg-desktop:~$ docker-compose -f ~/web-app-service/docker-compose.yml exec web-app bash
This is especially useful when a direct command isn't enough and you want to assess or troubleshoot some issue inside the running container.
Summary
There can be various ways to run commands inside container shells. Which of them is most effective honestly depends on the use-case scenario and its criticality within a real-world situation.
If you are interested in learning more on Docker commands, this article is for you.
I hope you found these quick tips useful for Linux and Docker. Your comments and feedback are always welcome.