1.5. Frontend

Frontend

Let’s create a frontend to demonstrate port-forwarding and container connections. We will run a simple Python web server that displays all users in our MariaDB.

By default, all containers are started in the bridge network, where no DNS service is available, so we can’t use container names. As a workaround, we use the IP of the container:

export ip=$(docker inspect mariadb-container-with-external-volume -f '{{ range.NetworkSettings.Networks }}{{ .IPAddress }}{{ end }}')

docker inspect <container> shows details about a running container in JSON format (run it yourself to explore). We filtered the JSON output to get only the container’s IP address.
Alternatively, we could filter the output with grep, as in docker inspect mariadb-container-with-external-volume | grep IPAddress, but our solution is more concise 😊.

Next, we’ll start the frontend container. Fortunately, an image is available online. If you’re interested, you can check the source code here . You see that you can pass the ip by using the env var servername

docker run -d --name frontend -e servername=$ip -e username=peter -e password=venkman quay.io/songlaa/container-lab-frontend

How do we access the frontend? Try connecting to the server using the container’s Docker-assigned IP address:

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

This will show only the IP of the container as output:

172.17.0.4

Since we don’t have a browser in the web shell, use curl http://172.17.0.4:5000 to view the page in your terminal. On a local installation, you could simply open http://172.17.0.4:5000 in your browser.

curl http://172.17.0.4:5000

Did this work? Well with a normal implementation yes. But in our shared lab we run rootless mode where direct connectivity the Container IP is not possible, because containers are not attached to the bridge network of the host.

So what do we do? We create a user defined network for our containers to communicate.

User defined network

docker network create rootless-net

Then we attach the db containers to this network:

docker stop mariadb-container-with-external-volume
docker rm mariadb-container-with-external-volume
docker run --name mariadb-container-with-external-volume -v volume-mariadb:/var/lib/mysql --network rootless-net -e MARIADB_ROOT_PASSWORD=my-secret-pw -d mariadb:12.0

Als frontend need to be attached, furthermore we forward port 5000 to localhost:

docker stop frontend
docker rm frontend
docker run -d --name frontend -e username=peter -e password=venkman -e servername=mariadb-container-with-external-volume -p 127.0.0.1:5000:5000 --network rootless-net quay.io/songlaa/container-lab-frontend

Now we curl the forwarded port:

curl http://localhost:5000

We successfully implemented a frontend for our backend, even in rootless mode.

Did you read the executed commands carefully? To check here are some questions:

🤔 By using a dedicated network we could leverage a feature which was not available before. Can you see it?

We don’t need to pass the IP to the frontend anymore but can use the hostname of the backend since docker provides DNS resolution inside those networks.

🤔 Is our Frontend publicly available?

Since we currently run inside Kubernetes no. But we also provided the localhost IP in the port mapping which maps the port only to the loopback interface.

🤔 Can containers in rootless mode talk to each other using the container IP?

Short Answer is No:
Rootless Docker uses slirp4netns (a user-space network stack) because it has no root privileges. As a result:
Containers run behind a user-space NAT.
Their “container IPs” exist only inside each container’s network namespace.
There is no real L2 / bridge network, so containers cannot directly talk to each other using those IPs. BUT when you create a user-defined network
✔ slirp4netns connects them using a user-space router
✔ Docker’s user-space DNS resolves container names
✔ slirp4netns sets up routing between those namespaces
This gives predictable connectivity with DNS (Containernames), but not with IPs