How To Connect To A Docker Container

How To Connect To A Docker Container

At this point, we are pretty familiar with getting containers running in Docker and how to monitor them from the cli or Docker desktop. Now we want to look at how to connect to a docker container while it is running. Connecting to a docker container is similar to how you would SSH into a remote machine to perform administrative tasks. With Docker, you don’t actually need SSH, as there are commands built into Docker that allow you to connect to a shell of running containers easily. Let’s see some ways to connect to a running Docker container now.


Docker Container Run -it

We’ve already seen the docker container run command in the prior Docker tutorials. It starts a container for us. During this process, we can connect to the container at the terminal right from startup. This leads us to a quick discussion of Docker Options. You might also see options referred to as a Flag. Here are the ones we are interested in for this exercise.

  • -i or –interactive Keep STDIN open even if not attached
  • -t or –tty Allocate a pseudo-TTY

With this knowledge in mind, the first way to connect to a Docker container is by running a new container in interactive mode. We are using -i and -t at the same time by simply typing -it. At the end of the command, we are instructing Nginx to start up a bash shell with /bin/bash

$ docker container run -it --name webserver nginx /bin/bash

This launches the webserver container, and then we are provided a bash prompt inside the container as indicated by the root@6b2693e38c19:/# prompt. This means we are the root user and the characters after the @ sign are the id of the container we are in. Once inside, we do a quick ls -al to see the contents of the container.

root@6b2693e38c19:/# ls -al
total 80
drwxr-xr-x   1 root root 4096 Oct  2 18:55 .
drwxr-xr-x   1 root root 4096 Oct  2 18:55 ..
-rwxr-xr-x   1 root root    0 Oct  2 18:55 .dockerenv
drwxr-xr-x   2 root root 4096 Sep  8 07:00 bin
drwxr-xr-x   2 root root 4096 Jul 10 21:04 boot
drwxr-xr-x   5 root root  360 Oct  2 18:55 dev
drwxr-xr-x   1 root root 4096 Sep 10 12:33 docker-entrypoint.d
-rwxrwxr-x   1 root root 1202 Sep 10 12:32 docker-entrypoint.sh
drwxr-xr-x   1 root root 4096 Oct  2 18:55 etc
drwxr-xr-x   2 root root 4096 Jul 10 21:04 home
drwxr-xr-x   1 root root 4096 Sep 10 12:33 lib
drwxr-xr-x   2 root root 4096 Sep  8 07:00 lib64
drwxr-xr-x   2 root root 4096 Sep  8 07:00 media
drwxr-xr-x   2 root root 4096 Sep  8 07:00 mnt
drwxr-xr-x   2 root root 4096 Sep  8 07:00 opt
dr-xr-xr-x 159 root root    0 Oct  2 18:55 proc
drwx------   2 root root 4096 Sep  8 07:00 root
drwxr-xr-x   3 root root 4096 Sep  8 07:00 run
drwxr-xr-x   2 root root 4096 Sep  8 07:00 sbin
drwxr-xr-x   2 root root 4096 Sep  8 07:00 srv
dr-xr-xr-x  11 root root    0 Oct  2 18:26 sys
drwxrwxrwt   1 root root 4096 Sep 10 12:33 tmp
drwxr-xr-x   1 root root 4096 Sep  8 07:00 usr
drwxr-xr-x   1 root root 4096 Sep  8 07:00 var
root@6b2693e38c19:/#

This shows us all the files inside the container that is based on the Nginx image. Once in the container, you can change config files, download files from the internet, or any other common administrative task that you might do from the shell of a running server. To leave the shell in the container, just type exit. Note that since all we did with this container was to run bash, once you exit the bash shell the container will stop running. This is because when you start an Nginx container and override the default command of running the Nginx process, there is nothing left to keep the container running once the shell is exited. In other words, containers only run as long as the command that it ran on startup runs.


Docker Container Exec -it

The approach that probably makes more sense is to connect to a container that is already running and doing its normal job. So let’s start a new Nginx webserver once again, but simply let the normal processes start. We will not add any commands to the end of the docker command.

$ docker container run --name webserver nginx

Now that the container is running, we can connect to it using the docker exec command.

$ docker container exec -it webserver bash

Once again we are connected to the container at a bash prompt. We do a pwd command and can see that we are at the root of the filesystem.

root@e9108992aa35:/# pwd
/

We can even view the default index.html file that is served if you were to browse to the container.

root@e9108992aa35:/# cat /usr/share/nginx/html/index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

This approach is likely the most useful and common.


Running One Off Commands

The section above made use of the -it flags. That makes it interactive and gives us a terminal to work in. By omitting the -it options, we can run commands from the Docker cli that get proxied into the container, ran, and then the results are printed back to the host terminal. To see how this works, we can redo the examples from above while leaving off the -it options.

> docker container exec webserver ls
bin
boot
dev
docker-entrypoint.d
docker-entrypoint.sh
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
>

We’ve been using the name of the container to determine which container we connect to. If you did not name your container, then you simply use the id of the container with the command instead.

> docker container exec e9108992aa35 ls
bin
boot
dev
docker-entrypoint.d
docker-entrypoint.sh
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

In this next example, we can use docker exec in a one-off style to view the nginx.conf file in the container.

> docker container exec webserver cat /etc/nginx/nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

Learn More


Summary

The main takeaway is that if you want to connect to a container, you’ll want to be using the -it options with either docker container run or docker container exec. When used with the run command, you’re starting a new container interactively. The more common and useful approach however is to use this flag with the docker container exec command.