Connect Containers with Link

DockerBeginner
Practice Now

Introduction

Docker is a powerful tool for deploying applications, but it can initially seem complex. This challenge will guide you through linking Docker containers to create a multi-container application. We'll begin with simple examples and gradually progress to a more complex application. Even if you're new to Docker, you should find this easy to follow. We'll explore how to make containers communicate with each other, which is a fundamental aspect of building robust applications with Docker.

Create an Image with Dockerfile

Before we can link containers, we need to have at least one containerized application. In this step, you'll create a Dockerfile for your my-app image. This Dockerfile will define the environment and the application to be run within the container.

Task

The goal of this step is to create a Dockerfile for your my-app image.

Requirements

  • Docker must be installed on your machine.
  • You should have an existing my-app application you wish to containerize.

Example Result

  1. Create the necessary files for the challenge:

    Create a new file named Dockerfile at the /home/labex/project/ path with the following content:

    • Use python:3.7-slim as the base image.
    • Set the working directory to /app.
    • Copy the current directory's contents into the container at /app.
    • Install the required packages.
    • Expose port 80 to the outside world.
    • Define an environment variable (though we don't use it in this example, keep the instruction).
    • Run app.py when the container starts.

    Create a file named app.py in your project directory /home/labex/project/ with the following content:

    import os
    
    os.system("wssh --address='0.0.0.0' --port=80")
    

    Create a file named requirements.txt in your project directory /home/labex/project/ with the following content:

    webssh==1.6.2
    
    labex:project/ $ pwd
    /home/labex/project
    labex:project/ $ ll
    total 12K
    -rw-r--r-- 1 labex labex 59 Jan 24 15:21 app.py
    -rw-r--r-- 1 labex labex 163 Jan 24 15:19 Dockerfile
    -rw-r--r-- 1 labex labex 14 Jan 24 15:21 requirements.txt
    
  2. Use the docker build command to build the my-app image.

    labex:project/ $ docker images | grep my-app
    my-app latest 266edf714faf 30 seconds ago 170MB
    
  3. Start a new container using the my-app image, and note the port mapping.

    labex:project/ $ docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    11f06f08d2d3 my-app "python app.py" 4 seconds ago Up 4 seconds 0.0.0.0:8080- hopeful_elgamal > 80/tcp
    
  4. Open a web browser and navigate to http://localhost:8080 to verify that your application is running correctly.

    Web app running in browser

Linking Two Docker Containers

Now that we have a containerized application, let's move on to linking containers. In this step, we will learn how to link two Docker containers, enabling them to communicate with each other. This process is key to creating multi-service applications within Docker.

Task

Launch Apache and MySQL service containers, then start a my_app container that links to both services so you can test the MySQL connection from inside my_app.

Requirements

  • You'll need two Docker containers: one running Apache and one running MySQL.
  • Start an additional my_app container that links to the Apache and MySQL containers.
  • Install the MySQL client inside my_app before testing the database connection.
  • Docker must be installed on your machine.

Hint

  • Remember to open a new terminal to start this step so it doesn't conflict with your previous container.

Example Result

Access MySQL from the my_app container after linking it to both services:

  1. Launch an Apache container named my_apache based on the httpd image, mapping host port 80 to container port 80.

    labex:project/ $ docker ps | grep my_apache
    a91a93216e84 httpd "httpd-foreground" 52 seconds ago Up 47 seconds 0.0.0.0:80- my_apache > 80/tcp
    
  2. Launch a MySQL container named my_mysql, setting the MYSQL_ROOT_PASSWORD environment variable to password, using the mysql image.

    labex:project/ $ docker ps | grep mysql
    0cb864cf97c6 mysql "docker-entrypoint.s…" 42 seconds ago Up 35 seconds 3306/tcp, 33060/tcp my_mysql
    
  3. Start a my_app container that links to both the MySQL and Apache containers. Note: The link is visible in the container configuration. You can inspect it with docker inspect my_app.

    labex:project/ $ docker ps | grep my_app
    859c201b7267 my-app "python app.py" 53 seconds ago Up 52 seconds 80/tcp my_app
    
  4. Use the docker exec command to access the MySQL command-line interface from the my_app container (you will need to adapt the command if you linked differently).

    Install the MySQL client inside my_app, then connect to the linked MySQL service:

    labex:project/ $ docker exec -it my_app bash
    root@859c201b7267:/app## apt-get update && apt install -y default-mysql-client
    root@859c201b7267:/app## mysql -h mysql -uroot -ppassword
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MySQL connection id is 8
    Server version: 8.3.0 MySQL Community Server - GPL
    
    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    MySQL [(none)]>
    

Linking Multiple Docker Containers and Using Environment Variables

Building on the previous step, this part adds two new ideas: one application container links to both services, and the container receives connection settings through environment variables. In Step 2, you only proved that linked containers can reach each other. In this step, you must start my_app2 with both --link options and the environment variables that describe the MySQL and Apache hosts.

Task

Launch three containers: one running Apache, one running MySQL, and one running a custom application. The custom application should be able to access both MySQL and Apache.

Requirements

  • You'll need three Docker containers: Apache, MySQL, and a custom application
  • Start my_app2 with both links and these environment variables: DB_HOST=mysql, DB_USER=root, DB_PASSWORD=password, and APACHE_HOST=apache
  • Install curl inside my_app2 before testing the Apache connection because the my-app image does not include it by default
  • Docker must be installed on your machine.

Example Result

  1. Launch an Apache and MySQL container as described in Step 2.

  2. Launch a custom application container named my_app2 that can access both MySQL and Apache.

    labex:project/ $ docker ps | grep app2
    8945b42659a6 my-app "python app.py" 15 seconds ago Up 15 seconds 80/tcp my_app2
    
  3. Enter my_app2, install curl, and run curl http://apache/ to confirm that the linked Apache container is reachable.

    <html>
      <body>
        <h1>It works!</h1>
      </body>
    </html>
    

Summary

In this challenge, you learned how to link Docker containers together to create multi-container applications. We progressed from a single container to linked pairs and finally to a three-container setup. You now have an understanding of how to leverage container links and the docker exec command to allow communication between different services, enabling you to build more complex applications. Keep experimenting, and have fun!

✨ Check Solution and Practice✨ Check Solution and Practice✨ Check Solution and Practice