Baeldung Pro – Ops – NPI EA (cat = Baeldung on Ops)
announcement - icon

Learn through the super-clean Baeldung Pro experience:

>> Membership and Baeldung Pro.

No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.

1. Overview

Docker is an operating system virtualization platform. We use Docker to develop, package, distribute, and run software as containers started from images. We can run isolated Docker containers with each having its own filesystem, networking, and IP address on a Docker Engine deployed on an underlying Linux OS. However, a Docker container running on a Linux (or other OS) machine is a Linux machine of its own, albeit a virtual machine. Therefore, we need to access the container before we can use the software running within it.

In this tutorial, we’ll learn about accessing or connecting to, Docker containers using a container’s name. The only prerequisite we need to perform is to install Docker on a supported Linux (Ubuntu etc.) platform. Docker can’t be installed/used directly on the Unix-like FreeBSD operating system.

We’ll discuss three methods for accessing a Docker container by its name. Further, we can select the method that best fits our use case.

2. Access a Docker Container Running on the Same Network

Docker container networking enables containers to communicate with each other and the host. It involves a networking interface, IP addresses, gateway, routing table, DNS services, and iptables, just like any other Linux networking.

We can create a custom network and connect multiple Docker containers to it, enabling them to communicate with each other using container names.

Let’s demonstrate with an example. To that end, let’s create a custom network called my-network, for example:

$ docker network create my-network
532c3423718dbf1919e020f97e959667f157218a72673078e2a53ec08683329f

Further, let’s run a container called test, which could be an nginx container, in the network:

$ docker run --name test --net my-network -d nginx:alpine
b2b4426c4598bed45a05f440c733f07590e4ff03dddef6b381a2fa31329f6736

Taking advantage of the interconnectivity that Docker networking provides, let’s run a second container using the busybox image and access the test container by its name:

$ docker run --net my-network busybox:latest ping test
PING test (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.097 ms
64 bytes from 172.20.0.2: seq=1 ttl=64 time=0.097 ms
64 bytes from 172.20.0.2: seq=2 ttl=64 time=0.074 ms
64 bytes from 172.20.0.2: seq=3 ttl=64 time=0.074 ms
64 bytes from 172.20.0.2: seq=4 ttl=64 time=0.081 ms
64 bytes from 172.20.0.2: seq=5 ttl=64 time=0.073 ms

Furthermore, it provides connectivity with no packet loss, as indicated by the statistics:

--- test ping statistics ---
30 packets transmitted, 30 packets received, 0% packet loss
round-trip min/avg/max = 0.070/0.082/0.227 ms

Indeed, we can connect to a container by its name.

3. Access a Running Docker Container Using the docker exec Command

We use the docker exec command to run a Linux command within a Docker container. The Linux command runs in the container’s default working directory. For this purpose, we access the bash (or other) shell in the container to run the Linux command. We can use the running container’s name when we access it using the docker exec command.

Let’s demonstrate with an example. Even though the docker run command creates a Docker container with an automatically generated name, we should run a named Docker container at the outset so that we can create an application stack accordingly. Let’s run a named Docker container called redis-stack for a Redis database stack using the redis/redis-stack Docker image:

$ docker run -d --name redis-stack -p 6379:6379 -p 8001:8001 redis/redis-stack:latest
Unable to find image 'redis/redis-stack:latest' locally
latest: Pulling from redis/redis-stack
6414378b6477: Pull complete
caaf2b7eab60: Pull complete
...
561bb2dc87d6: Pull complete
79e6e2693bf3: Pull complete
Digest: sha256:ca1e9182f3f6e1e40a766b1bb72f13fa89b8061477dd7843a79bf53e4b2307ae
Status: Downloaded newer image for redis/redis-stack:latest
5de6f3fca6e3898bd93548ebab2fbcb8c17a11d2db6ce4b99fbb497cbb9a1350

With the container running, let’s access it with the docker exec command using the container’s name. Furthermore, we can launch an interactive pseudo-TTY using the -it options:

$ docker exec -it redis-stack redis-cli

127.0.0.1:6379>

Let’s store a key/value pair in the Redis database:

127.0.0.1:6379> SET hello:1 "Hello Redis!"
OK
127.0.0.1:6379> GET hello:1
"Hello Redis!"
127.0.0.1:6379> quit

We can generally run any Linux command in a Docker container accessed by its name with the docker exec command if we have the requisite permissions to run a command and the command’s binaries exist in the container.

4. Access a Container by Its Name by Configuring the /etc/hosts File

The /etc/hosts is a plain-text file that maps IP addresses to their respective fully qualified domain names (FQDNs). When we want to access a Docker container by its name we can map the container name to its IP address in the /etc/hosts file. Having done so, we can access the container by its name.

Let’s demonstrate with an example. Let’s run a MySQL database container called mysql_container passing environment variable MYSQL_ALLOW_EMPTY_PASSWORD to allow empty password:

$ docker run 
  --name mysql_container 
  -e MYSQL_ALLOW_EMPTY_PASSWORD=yes 
mysql:8.4.2

8.4.2: Pulling from library/mysql
eba3c26198b7: Pull complete
fc6c33853069: Pull complete
...
2024-12-15T19:59:48.815058Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.4.2'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL.

Afterward, let’s list the running containers to verify that a container has started:

$ docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS         PORTS                 NAMES
f8c55be0ed5f   mysql:8.4.2   "docker-entrypoint.s…"   5 minutes ago   Up 5 minutes   3306/tcp, 33060/tcp   mysql_container

Let’s remember that a Docker container we run on a local machine runs as a remote machine. When we want to make a remote connection to a MySQL server running in a Docker container, we can only use the TCP/IP protocol and connect using the container’s IP address. Therefore, let’s first find the network IP address of the Docker container:

$ docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 
mysql_container

We can find the IP address in the output:

172.17.0.2

We can use this IP address as the host IP address of the MySQL server to connect to. However, we want to connect using the container name. Therefore, let’s map this IP address to the container name in the /etc/hosts file. We can use a file editor such as vi to open the file:

$ vi /etc/hosts

Add the container name to IP address mapping on a separate line along with the existing domain name mappings:

172.17.0.2 mysql_container
127.0.0.1 localhost

We need a MySQL client program to connect to the MySQL server running in the remote Docker container. Therefore, let’s install a MySQL Client program:

$ sudo apt install mysql-client-core-8.0

Having mapped the container’s IP address to its name, and installed the MySQL Client, we can connect to the container using its name for the host specification:

$ mysql 
  -h mysql_container 
  -P 3306 
  --protocol=tcp 
  -u root

Thereupon, we get connected to the MySQL server, and a MySQL Monitor is displayed. We can run SQL from the command prompt, such as list databases, to verify the connection:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.4.2 MySQL Community Server - GPL

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

5. Conclusion

In this article, we learned about the different methods to access a Docker container by its name. The first method we discussed uses multiple containers on the same network, enabling container access by name. The second method uses the docker exec command to access a running container. The third method uses the domain name mappings in the /etc/hosts file to access a container by its name.

As always, the Docker commands’ scripts used in this article are available over on GitHub.