Una guía para principiantes de Docker: cómo crear un lado del cliente / servidor con docker-compose

¿Eres desarrollador y quieres descubrir docker-compose? Este artículo está hecho para ti.

Después de una breve introducción sobre Docker-Compose, podrá crear su primera aplicación del lado del cliente / servidor con Docker.

Este artículo toma en consideración que conoce los conceptos básicos de Docker. Si no, ¡que no cunda el pánico! Le sugiero que lea mi primer artículo para descubrir Docker y aprender a crear su primera aplicación.

Una guía para principiantes de Docker: cómo crear su primera aplicación Docker

¿Eres desarrollador y quieres empezar con Docker? Este artículo está hecho para ti. Después de una breve introducción sobre qué es Docker y por qué usarlo, podrá crear su primera aplicación con Docker.

¿Qué es Docker-Compose?

Docker-Compose es una herramienta proporcionada por Docker. Para simplificarlo, esta herramienta se implementa para resolver problemas arquitectónicos en sus proyectos.

Como habrás notado en mi artículo anterior, creamos un programa simple que mostraba "¡Docker es mágico!" cuando fue lanzado.

Desafortunadamente, cuando eres un desarrollador, rara vez creas un programa independiente (un programa que no requiere ningún otro servicio para ejecutarse, como una base de datos).

Sin embargo, ¿cómo saber si necesita Docker-Compose? Es muy simple: si su aplicación requiere varios servicios para ejecutarse, necesita esta herramienta. Por ejemplo, si crea un sitio web que necesita conectarse a su base de datos para autenticar a los usuarios (aquí 2 servicios, sitio web y base de datos).

Docker-compose te ofrece la posibilidad de ejecutar todos estos servicios en un solo comando.

Diferencia entre Docker y Docker-Compose

Docker se utiliza para administrar un contenedor individual (servicio) para su aplicación.

Docker-Compose se utiliza para administrar varios contenedores al mismo tiempo para la misma aplicación. Esta herramienta ofrece las mismas características que Docker pero le permite tener aplicaciones más complejas.

Un caso de uso típico

Esta herramienta puede volverse muy poderosa y permitirle implementar aplicaciones con arquitecturas complejas muy rápidamente. Le daré un caso de estudio concreto que demostrará que lo necesita.

Imagínese, usted es el orgulloso creador de su software web.

Su solución ofrece dos sitios web. El primero permite a las tiendas crear su tienda en línea con solo unos pocos clics. El segundo está dedicado a la atención al cliente. Estos dos sitios interactúan con la misma base de datos.

Está comenzando a tener éxito y su servidor ya no es suficiente. Entonces, decide migrar todo su software a otra máquina.

Desafortunadamente, no usó docker-compose. Por lo tanto, tendrá que migrar y reconfigurar sus servicios uno tras otro, esperando que no se haya olvidado nada.

Si hubiera utilizado un docker-compose, en solo unos pocos comandos habría implementado toda su arquitectura en su nuevo servidor. Todo lo que tiene que hacer ahora es realizar algunas configuraciones y cargar la copia de seguridad de su base de datos para finalizar la migración.

Ahora creemos su primera aplicación del lado del cliente / servidor con Docker-Compose

Ahora que sabe para qué se utilizará docker-compose, ¡es hora de crear su primera aplicación del lado del cliente / servidor!

El objetivo de este tutorial es crear un pequeño sitio web (servidor) en Python que contendrá una oración. Esta oración debe ser recuperada por un programa (cliente) en Python que mostrará la oración.

Nota: Este tutorial toma en consideración que ya instaló Docker en su computadora y que tiene los conceptos básicos. Si este no es el caso, los invito a consultar mi artículo anterior.

1. Crea tu proyecto

Para crear su primera aplicación cliente / servidor, lo invito a crear una carpeta en su computadora. Debe contener en la raíz los siguientes archivos y carpetas:

  • Un archivo ' docker-compose.yml ' (archivo docker-compose que contendrá las instrucciones necesarias para crear los diferentes servicios).
  • Una carpeta de ' servidor ' (esta carpeta contendrá los archivos necesarios para configurar el servidor).
  • Una carpeta ' cliente ' (esta carpeta contendrá los archivos necesarios para configurar el cliente).

Normalmente debería tener esta arquitectura de carpeta:

. ├── client/ ├── docker-compose.yml └── server/ 2 directories, 1 file

2. Crea tu servidor

Para comenzar con recordatorios de los conceptos básicos de Docker, comenzaremos por crear el servidor.

2a. Crear archivos

Muévase a su carpeta ' servidor ' y cree los siguientes archivos:

  • Un archivo ' server.py ' (archivo python que contendrá el código del servidor).
  • Un archivo ' index.html ' (archivo html que contendrá la oración que se mostrará).
  • Un archivo ' Dockerfile ' (archivo docker que contendrá las instrucciones necesarias para crear el entorno del servidor).

Normalmente, debería tener esta arquitectura de carpeta en la siguiente ruta ' servidor / ':

. ├── Dockerfile ├── index.html └── server.py 0 directories, 3 files

2b. Edita el archivo Python

Puede agregar el siguiente código al archivo ' server.py ':

#!/usr/bin/env python3 # Import of python system libraries. # These libraries will be used to create the web server. # You don't have to install anything special, these libraries are installed with Python. import http.server import socketserver # This variable is going to handle the requests of our client on the server. handler = http.server.SimpleHTTPRequestHandler # Here we define that we want to start the server on port 1234. # Try to remember this information it will be very useful to us later with docker-compose. with socketserver.TCPServer(("", 1234), handler) as httpd: # This instruction will keep the server running, waiting for requests from the client. httpd.serve_forever()

Este código le permitirá crear un servidor web simple dentro de esta carpeta. Recuperará el contenido del archivo index.html para compartirlo en una página web.

2c. Edite el archivo Html

Puede agregar la siguiente oración al archivo ' index.html ':

Docker-Compose is magic!

Este archivo será compartido por el servidor cuando se inicie y se mostrará esta oración.

2d. Edite el archivo Docker

Aquí crearemos un Dockerfile básico que se encargará de ejecutar nuestro archivo Python. Usaremos la imagen oficial creada para ejecutar Python.

# Just a remember, dockerfile must always start by importing the base image. # We use the keyword 'FROM' to do that. # In our example, we want to import the python image (from DockerHub). # So, we write 'python' for the image name and 'latest' for the version. FROM python:latest # In order to launch our python code, we must import the 'server.py' and 'index.html' file. # We use the keyword 'ADD' to do that. # Just a remember, the first parameter 'server.py' is the name of the file on the host. # The second parameter '/server/' is the path where to put the file on the image. # Here we put files at the image '/server/' folder. ADD server.py /server/ ADD index.html /server/ # I would like to introduce something new, the 'WORKDIR' command. # This command changes the base directory of your image. # Here we define '/server/' as base directory (where all commands will be executed). WORKDIR /server/

3. Crea tu cliente

In order to continue with reminders of Docker’s basics, we will create the client.

3a. Create files

Move to your ‘client’ folder and create the following files:

  • A ‘client.py’ file (python file that will contain the client code).
  • A ‘Dockerfile’ file (docker file that will contain the necessary instructions to create the environment of the client).

Normally you should have this folder architecture in the following path ‘client/’:

. ├── client.py └── Dockerfile 0 directories, 2 files

3b. Edit the Python file

You can add the following code to the ‘client.py’ file:

#!/usr/bin/env python3 # Import of python system library. # This library is used to download the 'index.html' from server. # You don't have to install anything special, this library is installed with Python. import urllib.request # This variable contain the request on '//localhost:1234/'. # You must wondering what is '//localhost:1234'? # localhost: This means that the server is local. # 1234: Remember we define 1234 as the server port. fp = urllib.request.urlopen("//localhost:1234/") # 'encodedContent' correspond to the server response encoded ('index.html'). # 'decodedContent' correspond to the server response decoded (what we want to display). encodedContent = fp.read() decodedContent = encodedContent.decode("utf8") # Display the server file: 'index.html'. print(decodedContent) # Close the server connection. fp.close()

This code will allow you to get the content of the server web page and to display it.

3c. Edit the Docker file

En cuanto al servidor, crearemos un Dockerfile básico que se encargará de ejecutar nuestro archivo Python.

# Same thing than the 'server' Dockerfile. FROM python:latest # Same thing than the 'server' Dockerfile. # We import 'client.py' in '/client/' folder. ADD client.py /client/ # I would like to introduce something new, the 'WORKDIR' command. # This command changes the base directory of your image. # Here we define '/client/' as base directory. WORKDIR /client/

4. Volver a Docker-Compose

Como habrás notado, hemos creado dos proyectos diferentes, el servidor y el cliente, ambos con un Dockerfile.

Hasta ahora, nada ha cambiado con respecto a lo básico que ya conoce.

Ahora vamos a editar el ' docker-compose.yml ' en la raíz del repositorio.

Nota: Docker-Compose es muy completo, este artículo tiene como objetivo brindarle un ejemplo concreto y típico. Por eso no verá todas las palabras clave.
# A docker-compose must always start by the version tag. # We use "3" because it's the last version at this time. version: "3" # You should know that docker-composes works with services. # 1 service = 1 container. # For example, a service maybe, a server, a client, a database... # We use the keyword 'services' to start to create services. services: # As we said at the beginning, we want to create: a server and a client. # That is two services. # First service (container): the server. # Here you are free to choose the keyword. # It will allow you to define what the service corresponds to. # We use the keyword 'server' for the server. server: # The keyword "build" will allow you to define # the path to the Dockerfile to use to create the image # that will allow you to execute the service. # Here 'server/' corresponds to the path to the server folder # that contains the Dockerfile to use. build: server/ # The command to execute once the image is created. # The following command will execute "python ./server.py". command: python ./server.py # Remember that we defined in'server/server.py' 1234 as port. # If we want to access the server from our computer (outside the container), # we must share the content port with our computer's port. # To do this, the keyword 'ports' will help us. # Its syntax is as follows: [port we want on our machine]:[port we want to retrieve in the container] # In our case, we want to use port 1234 on our machine and # retrieve port 1234 from the container (because it is on this port that # we broadcast the server). ports: - 1234:1234 # Second service (container): the client. # We use the keyword 'client' for the server. client: # Here 'client/ corresponds to the path to the client folder # that contains the Dockerfile to use. build: client/ # The command to execute once the image is created. # The following command will execute "python ./client.py". command: python ./client.py # The keyword 'network_mode' is used to define the network type. # Here we define that the container can access to the 'localhost' of the computer. network_mode: host # The keyword'depends_on' allows you to define whether the service # should wait until other services are ready before launching. # Here, we want the 'client' service to wait until the 'server' service is ready. depends_on: - server

5. Compile Docker-Compose

Una vez que el docker-compose está configurado, su aplicación cliente / servidor debe estar construida. Este paso corresponde al comando 'docker build' pero aplicado a los diferentes servicios.

$ docker-compose build

6. Ejecute Docker-Compose

¡Tu docker-compose está construido! ¡Ahora es el momento de empezar! Este paso corresponde al comando 'docker run' pero aplicado a los diferentes servicios.

$ docker-compose up

Ahí tienes, eso es todo. Normalmente debería ver "Docker-Compose is magic!" que se muestra en su terminal.

Nota: Como se indica en el tutorial, su servicio de 'servidor' usa el puerto 1234 de su computadora para distribuir su contenido. Si abre la página '// localhost: 1234 /' en su computadora, debería ver 'Docker-Compose is magic!'.

El código está disponible

Si quieres recuperar el código completo para descubrirlo de forma más sencilla o ejecutarlo, lo he puesto a tu disposición en mi Github.

-> GitHub: ejemplo de Docker-Compose de servidor cliente

Comandos útiles para Docker

Como de costumbre, he preparado una lista de pedidos que pueden resultarle útiles con docker-compose.

  • Stops containers and removes containers, images… created by ‘docker-compose up’.
$ docker-compose down
  • Displays log output from services (example: ‘docker-compose logs -f client’).
$ docker-compose logs -f [service name]
  • Lists containers.
$ docker-compose ps
  • Executes a command in a running container (example: ‘docker-compose exec server ls’).
$ docker-compose exec [service name] [command]
  • Lists images.
$ docker-compose images

Conclusion

You can refer to this post every time you need a simple and concrete example on how to create a client/server-side with docker-compose. If you have any questions or feedback, feel free to ask.

Don't miss my content by following me on Twitter and Instagram.

You can find other articles like this on my website: herewecode.io.

Want more?

  • Each week get a motivational quote with some advice, a short tutorial into a few slides, and one developer's picture on Instagram.
  • Sign-up for the newsletter and get the latest articles, courses, tutorials, tips, books, motivation, and other exclusive content.