[Translation] Docker Compose Beginner's Guide

[Translation] Docker Compose Beginner's Guide

The author of the article, the translation of which we are publishing today, says that it is intended for those developers who want to learn Docker Compose and go to create their first client server application using docker. It is assumed that the reader of this material is familiar with the basics of Docker. If this is not the case, you can take a look at this series of materials on this publication where the Docker fundamentals are reviewed along with the basics of Kubernetes, and on this article for beginners.


What is Docker Compose?

Docker Compose is a tool included with Docker. It is designed to meet the challenges associated with deploying projects.

While learning the basics of Docker, you might have come up with the creation of simplest applications that work autonomously, independent of, for example, from external data sources or from certain services. In practice, such applications are rare. Actual projects usually include a whole set of collaborative applications.

How do you know if you need to use Docker Compose when you deploy a project? In fact - very simple. If several services are used to make this project work, then Docker Compose may be useful to you. For example, in a situation where they create a website that, in order to perform user authentication, needs to connect to the database. Such a project may consist of two services - the one that provides the website and the one that is responsible for maintaining the database.

The Docker Compose technology, if it is simplified to describe it, allows, with the help of one command, to launch many services.

Difference between Docker and Docker Compose

Docker is used to manage the individual containers (services) that make up an application.

Docker Compose is used to simultaneously manage multiple containers that are part of an application. This tool offers the same features as Docker, but allows you to work with more complex applications.

Docker (separate container) and Docker Compose (multiple containers)

Typical Docker Compose Use Case

Docker Compose is, in capable hands, a very powerful tool that allows you to very quickly deploy applications that have a complex architecture. Now we will look at an example of the practical use of Docker Compose, the analysis of which will allow you to evaluate the advantages that the use of Docker Compose will give you.

Imagine that you are a developer of a web project. This project includes two websites. The first allows business people to create, just a few mouse clicks, online shopping. The second is aimed at customer support. These two sites interact with the same database.

Your project is becoming more popular, and it turns out that the capacity of the server on which it runs is no longer enough. As a result, you decide to transfer the entire project to another machine.

Unfortunately, you didn't use something like Docker Compose.Therefore, you will have to transfer and reconfigure services one by one, hoping that you will not forget anything in the process of this work.

If you use Docker Compose, then transferring your project to a new server is an issue that is solved by executing several commands. In order to complete the transfer of the project to a new location, you only need to perform some settings and upload a backup copy of the database to the new server.

Developing a client-server application using Docker Compose

Now that you know what we're going to use Docker Compose for, it's time to create your first client/server application using this tool. Namely, we are talking about the development of a small website (server) in Python, which can produce a file with a piece of text. This file is requested from the server by a program (client), also written in Python. After receiving the file from the server, the program displays the text stored in it on the screen.

Pay attention to the fact that we are counting on the fact that you own the fundamentals of Docker, and on the fact that you already have the Docker platform installed.

Let's get to work on the project.

▍1. Creating a project

In order to build your first client-server application, I suggest starting with creating a project folder. It should contain the following files and folders:

  • The docker-compose.yml file. This is the Docker Compose file, which will contain the instructions necessary to start and configure the services.
  • The server folder. It will contain the files needed to make the server work.
  • The client folder. This will contain the client application files.

As a result, the contents of the main folder of your project should look like this:

 Client── client/
 Do── docker-compose.yml
 Server── server/
 2 directories, 1 file  

▍2. Create server

Here we are, in the process of creating the server, will touch on some basic things concerning Docker.

2a. Creating files

Go to the server folder and create the following files in it:

  • The server.py file. It will contain the server code.
  • The index.html file. This file will contain a piece of text that the client application should display.
  • The Dockerfile file. This is a Docker file that will contain the instructions needed to create the server environment.

Here’s what your server/ folder should look like:

 Do── Dockerfile
 Index── index.html
 Server── server.py
 0 directories, 3 files  

2b. Editing a Python file.

Add the following code to the server.py file:

  #!/usr/bin/env python3

 # Import python system libraries.
 # These libraries will be used to create a web server.
 # You do not need to install something special, these libraries are installed along with Python.

 import http.server
 import socketserver

 # This variable is needed to process client requests to the server.

 handler = http.server.SimpleHTTPRequestHandler

 # Here we indicate that we want to start the server on port 1234.
 # Try to remember this information, as they will be very useful in the future, when working with docker-compose.

 with socketserver.TCPServer (("", 1234), handler) as httpd:

  # With this command, the server will run continuously, waiting for requests from the client.

  httpd.serve_forever ()  

This code allows you to create a simple web server. It will give clients a index.html file, the contents of which will later be displayed on a web page.

2c. Editing an html file

In the file index.html add the following text:

  Docker-Compose is magic!  

This text will be transmitted to the client.

2d. Editing the Dockerfile

Now we will create a simple Dockerfile file that will be responsible for organizing the runtime environment for the Python server. As a basis for the image being created, we will use in an official way , designed to run programs written in Python. Here are the contents of the Dockerfile:

  # Just in case, I remind you that the Dockerfile must always begin with the import of the base image.
 # The keyword 'FROM' is used for this.
 # Here we need to import a python image (with DockerHub).
 # As a result, we specify 'python' as the name of the image, and 'latest' as the version.

 FROM python: latest

 # In order to run code written in Python in a container, we need to import the 'server.py' and 'index.html' files.
 # In order to do this, we use the 'ADD' keyword.
 # The first parameter, 'server.py', is the name of the file stored on the computer.
 # The second parameter, '/server/', is the path where the specified file should be placed in the image.
 # Here we put the file in the '/server/' image folder.

 ADD server.py/server/
 ADD index.html/server/

 # Here we will use the 'WORKDIR' command, possibly new for you.
 # It allows you to change the working directory of the image.
 # As such a directory in which all commands will be executed, we set '/server/'.


Now let's work on the client.

▍3. Client creation

Creating the client part of our project, we will in passing recall some of the Docker basics.

3a. Creating files

Go to your client project folder and create the following files in it:

  • The client.py file. There will be a client code.
  • The Dockerfile file. This file plays the same role as the similar file in the server folder. Namely, it contains a statement describing the creation of an environment for executing client code.

As a result, your client/ folder at this stage should look like this:

 Client── client.py
 Do── Dockerfile
 0 directories, 2 files  

3b. Editing a Python file

Add the following code to the client.py file:

  #!/usr/bin/env python3

 # Import the Python system library.
 # It is used to download the 'index.html' file from the server.
 # Nothing special needs to be installed, this library is installed along with Python.

 import urllib.request

 # This variable contains a request for 'http://localhost: 1234/'.
 # Perhaps now you are wondering what is 'http://localhost: 1234'.
 # localhost indicates that the program works with a local server.
 # 1234 is the port number that you were asked to remember when setting up the server code.

 fp = urllib.request.urlopen ("http://localhost: 1234/")

 # 'encodedContent' corresponds to the encoded server response ('index.html').
 # 'decodedContent' corresponds to the decoded response of the server (there will be what we want to display on the screen).

 encodedContent = fp.read ()
 decodedContent = encodedContent.decode ("utf8")

 # Display the contents of the file received from the server ('index.html').

 print (decodedContent)

 # Close the connection to the server.

 fp.close ()  

Thanks to this code, the client application can download data from the server and display it on the screen.

3c. Editing the Dockerfile

As in the case of the server, we create a simple Dockerfile for the client, responsible for creating the environment in which the client Python application will run.Here's the code for the client’s Dockerfile :

  # Same as in server Dockerfile.

 FROM python: latest

 # Import 'client.py' into the '/client/' folder.

 ADD client.py/client/

 # Set as the working directory '/client/'.


▍4. Docker Compose

As you can see, we have created two different projects: a server and a client. Each one has its own Dockerfile file. Until now, everything that happens does not go beyond the basics of working with Docker. Now we begin to work with Docker Compose. To do this, refer to the file docker-compose.yml , located in the root folder of the project.

Please note that here we are not trying to consider absolutely all the commands that can be used in docker-compose.yml . Our main goal is to make out a practical example that gives you a basic knowledge of Docker Compose.

Here's the code to put in the docker-compose.yml file:

  # The docker-compose file must start with a version tag.
 # We use "3" as this is the most recent version at the time of this writing.

 version: "3"

 # Please note that docker-composes works with services.
 # 1 service = 1 container.
 # A service can be a client, server, database server ...
 # The section in which services will be described begins with 'services'.


  # As already mentioned, we are going to create client and server applications.
  # This means that we need two services.
  # First service (container): server.
  # You can call it the way a developer needs.
  # The clear name of the service helps to determine its role.
  # Here we use the 'server' keyword to name the corresponding service.

  # The "build" keyword allows you to set
  # path to the Dockerfile file to be used to create the image,
  # which will allow to start the service.
  # Here, 'server/' corresponds to the path to the server folder,
  # which contains the corresponding Dockerfile.

  build: server/

  # The command to be run after creating the image.
  # The following command means running "python ./server.py".

  command: python ./server.py

  # Recall that port 1234 is specified as a port in 'server/server.py'.
  # If we want to access the server from our computer (being outside the container),
  # we need to organize the redirection of this port to the port of the computer.
  # The 'ports' keyword will help us.
  # When using it, the following construction is used: [computer port]: [container port]
  # In our case, you need to use computer port 1234 and organize its connection with the port
  # 1234 containers (as it is on this port server
  # waiting for requests).

  - 1234: 1234

  # Second service (container): client.
  # This service is named 'client'.

  # Here 'client/corresponds to the path to the folder that contains
  # Dockerfile file for the client part of the system.

  build: client/

  # The command to be run after creating the image.
  # The following command means running "python ./client.py".
  command: python ./client.py

  # The keyword 'network_mode' is used to describe the type of network.
  # Here we indicate that the container can access the computer 'localhost'.

  network_mode: host

  # The 'depends_on' keyword allows you to specify whether a service should
  # Before you start, wait for other services to be ready for work.
  # We need the 'client' service to wait for the availability of the 'server' service.
  - server  

▍5. Build a project

After all the necessary instructions have been entered into docker-compose.yml , the project needs to be assembled.This step of our work resembles the use of the docker build command, but the corresponding command relates to several services:

  $ docker-compose build  

▍6. Launching a project

Now that the project is complete, it's time to start it. This step of our work corresponds to the step in which, when working with separate containers, the docker run command is executed:

  $ docker-compose up  

After executing this command, the text loaded by the client from the server should appear in the terminal: Docker-Compose is magic! .

As already mentioned, the server uses the port of the computer 1234 to service client requests. Therefore, if you go to your browser at http://localhost: 1234/, it will display a page with the text Docker-Compose is magic! .

Useful Commands

Consider some commands that may come in handy when working with Docker Compose.

This command allows you to stop and delete containers and other resources created by the docker-compose up command:

  $ docker-compose down  

This command prints service logs:

  $ docker-compose logs -f [service name]  

For example, in our project you can use it in this form: $ docker-compose logs -f [service name] .

With this command you can display a list of containers:

  $ docker-compose ps  

This command allows you to execute a command in a running container:

  $ docker-compose exec [service name] [command]  

For example, it might look like this: docker-compose exec server ls .

This command allows you to display a list of images:

  $ docker-compose images  


We looked at the basics of working with Docker Compose technology, the knowledge of which will allow you to use this technology and, if you wish, to begin to study it in more depth. Here is the repository with the project code that we reviewed here.

Dear readers! Do you use Docker Compose in your projects?

<< a>

Source text: [Translation] Docker Compose Beginner's Guide