How to Access Docker Containers
When you are working with Docker containers, most of the time they are sent to work in a background process. So, how do you access them?
There are a couple of ways you can interpret accessing a Docker container:
- Running a command inside of a container
- Starting a shell session in a container
- Accessing the standard output, input or error of a container
- Seeing the logs of the script your container is running
If you want to know how to SSH into a Docker container, the answer is — you shouldn’t.
In this post I will show you how to achieve all of the above with the available features of Docker. No SSH needed.
Getting Container Info
To interact with a Docker container, you must know either its id
or name
. And, the container must be running, of course.
If your container is not running, here’s how to get it going:
-
Run
docker container ls -a
command to see all containersdocker container ls -a --format "table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Status}}" CONTAINER ID NAMES IMAGE STATUS 22aac9c3624b my-app express-app Exited (143) 17 hours ago
I am running the
ls
command with a custom--format
argument to display only the information I need. Omit the argument to use the default formatting. -
Run
docker start <container>
command and substitute<container>
with eitherid
orname
of your container from previous stepdocker start <container>
When your container is running, you can use docker ps
command to find out its id
and name
.
docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Image}}\t{{.Status}}"
CONTAINER ID NAMES IMAGE STATUS
22aac9c3624b my-app express-app Up 6 minutes
Copy either the container id
or name
and replace <container>
with that value from now on in the upcoming examples. In the case above, you could either use 22aac9c3624b
or my-app
.
Running Commands Inside of Container
To run a command inside a Docker container, use the docker exec
command.
docker exec <container> whoami
The above command prints the name of the user of your container. In my case, it prints node
.
To run the command as another user, pass docker exec
command the -u
(short of --user
) argument.
docker exec -u root <container> whoami
In this case, the command prints root
.
And of course, you can pass arguments to the command you want to run inside the container.
docker exec <container> ls -la /
In this example you can see how to pass -la
and /
path as arguments to the ls
command.
Accessing the Shell of a Container
You can access the shell of a container by modifying the docker exec
command with a few arguments.
Here’s how to start a new shell session inside a container.
docker exec -i -t <container> <shell>
This is as close as it gets to connecting to a Docker container with SSH. That’s why I said in the beginning that you don’t really need SSH.
- The
-i
(--interactive
) and-t
(--tty
) arguments are required for the shell session to work properly - Replace
<shell>
with the name of the shell you want to use
Here’s how to start an sh
session in a container:
docker exec -it my-container sh
You can use other shells like bash
, but Docker containers usually don’t have them installed.
docker exec -it <container> bash
So the above command produces the following error:
OCI runtime exec failed: exec failed: unable to start container process: exec: “bash”: executable file not found in $PATH: unknown
Stick to sh
in that case.
Otherwise, you can try passing the path to the shell if it’s not global in your container.
docker exec -it <container> /bin/bash
To log in to the container as another user, add the -u
argument to the command.
docker exec -it -u <user> <container> sh
Accessing Standard Output, Input And Error
Sometimes getting inside the container itself is not enough. Some scripts you run in your container can accept input or produce some output you want to listen to.
For example, a script running a game server inside a container might listen to commands through standard input (stdin
).
You can use docker attach
command to attach to your container and interact with the running script.
docker attach <container>
The docker attach
command will also output the standard output (stdout
) and error (stderr
) of the container script in your terminal.
Pressing Ctrl+c
will send SIGKILL
to the container and stop it. So, how do you detach from the container without stopping it? There are two ways.
First, try pressing Ctrl+p
followed by Ctrl+d
. It will only work if your container was created with -i
and -t
arguments like so:
docker run -it <image>
You can override the exit sequence by adding --detach-keys
argument to the docker attach
command.
docker attach --detach-keys="Q" <container>
This will allow you to detach by pressing Shift+q
(Q
).
Second option is to add --sig-proxy=false
to the docker attach
command. This works when you have created your container without the -i
and -t
arguments.
docker attach --sig-proxy=false <container>
You can now press Ctrl+c
to detach from the container. This option isn’t ideal, because you can’t interact with standard input. It’s limited to just showing the output, which can be done in a better way by seeing the container logs.
Seeing Container Logs
If you just want to see the output of the container script, you don’t have to go through all the trouble of attaching to a container.
You can see the output of a container’s script with docker logs
command.
docker logs <container>
This will print the logs to your terminal.
You can pass docker logs
command the -f
argument to continuously keep printing the output of your script to your terminal. I find this much more useful.
docker logs -f <container>
Unlike with docker attach
, you can press Ctrl+c
to stop printing logs to your terminal without stopping the container.
Reading Logs of Docker Compose Services
If you are running multiple containers within a project with docker compose
, you can use docker compose logs
instead to see the output of all your services.
docker compose logs -f
To see the logs of just one service, pass docker compose logs
the name of the service.
docker compose logs -f <service>
You can find out the names of your services by running the following command:
docker compose ps --services
You can also print the logs of multiple services at once.
docker compose logs -f <service-one> <service-two>
Using Tools To Access Containers
Memorizing all these commands can be tough. Or, maybe you would like to have a user interface from where you can run them. For that you can use the following tools:
- ctop — simple overview of containers, can access logs and shell
- lazydocker — more advanced but more complete option
Summary
To conclude what you have learned in this article, here’s how to access a Docker container:
- Use
docker exec
to run a command inside of a container - Complement
docker exec
with-it
arguments and runsh
command for shell access - Use
docker attach
to interact with standard input of the container’s script - See the output of the script with
docker logs