Usando Docker en un entorno de desarrollo

Introducción

El mundo del desarrollo ha vivido una gran evolución en su corta historia. En sus inicios, se instalaban los servicios habituales para llevar a cabo un proyecto web en PHP, como puede ser Apache y Mysql. Posteriormente llegaron los development environment, con sus diferentes variantes, WAMP, MAMP y LAMP. Estos supusieron un gran paso hacia delante, facilitando la administración del entorno de forma mas amigable. Vagrant fue el precursor de este flujo de trabajo, a través del cual, nos permitía interactuar con una máquina virtual de forma automática. Pero en 2006, un grupo de investigadores de Google, propició el siguiente gran salto: los contenedores.

Un contenedor encapsula el proceso en ejecución y lo aísla del resto, como si de una máquina virtual se tratase. Esto permite optimizar el uso de recursos y simplifica la gestión de los mismos. Es posible crear estos contenedores con una instancia de linux corriendo a través de las tecnologías: namespaces, cgroups y chroot. Pero en este caso, Docker es un gran aliado, el cual nos proporciona una serie de herramientas que nos van a ayudar a diseñar estos contenedores de forma muy eficiente. Como alternativa a Docker, existe LXC y su versión moderna, LXD, el cual busca ofrecer una distribución sin dependencias de terceros.

Docker nos proporciona un lugar donde subir las imágenes de forma pública y poder utilizarlas, dockerhub. Existen una gran cantidad de contenedores elaborados por la comunidad tanto de servicio, como pueden ser PHP, el cual veremos en este artículo, redis, o node y contenedores que empaquetan una aplicación completa como nextcloud. La tecnología de los contenedores está ampliamente extendida y eso ha propiciado que haya gran cantidad de servicios que ofrezcan soporte entre otros, aws, google y azure. Además, también incluyen soporte para arquitecturas mas avanzadas con la ayuda de Kubernetes o Docker Swarm, los cuales permiten orquestar el despliegue de múltiples instancias.

Qué es Docker

Docker es un conjunto de herramientas que nos permite abstraer la virtualización de un contenedor y ejecutar aplicaciones en él.

Sus principales ventajas son:

  • Entornos replicables, donde la ejecución del contenedor no está sujeta al sistema operativo.
  • Son más ligeros que una VM completa.
  • Potabilidad y empaquetado de la aplicación para desplegarlo donde sea necesario, ya sea en local o remoto.
  • Aislamiento del resto de servicios, si reducimos la superficie de error es menos propensa a fallos.
  • Permite un rápido desarrollo escribiendo un yaml de configuración o a través del terminal.
  • Podemos automatizar gran cantidad de tareas.
  • Los cambios en el contenedor se pueden introducir en un sistema de control de versiones.

Para poder crear contenedores con Docker, tenemos dos opciones: ejecutar un contenedor ya creado con el terminal o añadir un archivo Dockerfile y compilarlo, que en Docker se hace a través del comando build. Siempre que queramos ejecutarlo desde el terminal, es necesario que previamente esté creado, ya sea en dockerhub (y/o registros privados) o previamente en nuestra máquina.

Para crear nuestro contenedor, deberemos ir a la documentación de Docker relativa al formato del archivo que describe el proceso de creación llamado del Dockerfile. Como podrás observar, hay una serie de palabras reservadas que siempre se escriben en mayúsculas a través de las cuales describiremos los pasos que debe seguir para llevar a cabo la creación del contenedor.

Cómo se usa

Previamente a este paso, debes tener instalado el servicio de Docker en tu máquina como indican en la documentación.

Con el siguiente comando, vamos a ejecutar nuestro primer contenedor, que lo que hará será imprimir por pantalla un texto, interpretando nuestro archivo script.php

Con run, le pedimos a docker que ejecute el contenedor php:8.0-cli, el cual está formado por una instalación de PHP con el tag 8.0-cli, que incluye la versión de PHP 8.0 y es mas pequeña en tamaño y uso de recursos que 8.0-apache por ejemplo, la cual incluye un servidor web de Apache. Existen una gran cantidad de tags en este contenedor, aquí puedes verlas todas.

Las opciones que hemos usado para ejecutar el contenedor son las siguientes (en la documentación de docker encontrarás mas información al respecto de la sintaxis y los argumentos que soporta el comando run):

  • –rm: elimina el contenedor cuando termina su ejecución
  • -v: que archivos queremos montar dentro del contenedor
  • -w: donde va a establecer la raíz para buscar nuestros archivo
  • php:8.0-cli: el tag de versión que queremos usar
  • php: comando a ejecutar dentro del contenedor
  • script.php: argumentos del comando

Tras ejecutar el comando, en la salida se observa como el contenedor de PHP está compuesto por varias capas, que Docker ha podido encontrar en la caché, y las que no las ha obtenido. En caso de que nunca hayas ejecutado un contenedor, verás como pullea todas las capas.

En el siguiente caso, vamos a elaborar un sencillo Dockerfile y buildear nosotros la imagen. Para ello, optaremos por no compartir un volumen. Generalmente la compartición de volúmenes suele ser usada en la etapa de desarrollo, para producción, el entorno debe ser replicable y estar aislado, y esto implica que debe poderse ejecutar por si mismo tanto dependencias como código de la aplicación. De esta forma, podríamos proceder a desplegarlo en un servicio que soporte este tipo de tecnología como hemos comentado anteriormente.

El archivo está compuesto por una serie de instrucciones que se escriben en mayúsculas y le indican a Docker que debe llevar a cabo:

  • FROM php:8.0-cli: «importamos» la imagen de PHP.
  • RUN mkdir -p /usr/src/myapp: creamos el directorio donde vamos a copiar nuestro script de consola.
  • COPY script.php /usr/src/myapp: copiamos nuestro script a ejecutar en el interior de nuestro contenedor.
  • WORKDIR /usr/src/myapp: establecemos la raíz donde buscar los archivos a ejecutar, el equivalente a -w. Este paso lo podemos saltar si simplemente usamos la ruta absoluta del archivo.
  • CMD [ «php», «./script.php» ]: le indicamos que comando ejecutar, previamente se lo habíamos proporcionado como argumento php script.php.

Para compilar nuestra imagen, usamos el comando docker build con la opción -t le añadimos el tag. Es lo que hemos usado antes con la imagen de PHP. Esto va a compilar la imagen y la añadirá a nuestro registro privado. De esta forma, cuando queramos ejecutarla, la buscará ahí y no en dockerhub.

En nuestro siguiente paso, ejecutaremos la imagen a través del siguiente comando:

Y ejecutando la imagen, vemos el mismo resultado que con el comando de consola.

Conclusión

A lo largo del artículo hemos visto lo sencillo que es crear un entorno replicable y aislado del resto de servicios sin tener que preocuparnos por las dependencias que necesite el proyecto en función del sistema operativo o anteriores instalaciones en nuestra máquina como sucedía anteriormente.

Podemos probar cualquier tipo de servicio, sin tener que preocuparnos por saber cómo se instala, las dependencias que tiene o cómo se configura, simplemente con ejecutar el servicio con los parámetros que nos indiquen en la documentación es suficiente. Esto aporta una gran capacidad de maniobra como desarrolladores y permite centrar la visión en lo importante, la solución óptima al problema.

Es muy aconsejable integrar la filosofía de los contenedores en todos los ámbitos posibles del desarrollo, lo que propicia la automatización y cohesiona las acciones del equipo en la misma dirección. Podemos tener un contenedor para ejecutar composer, empaquetar en un contenedor una aplicación de terminal en PHP que usemos en la empresa con las reglas predefinidas que se han acordado por ejemplo para las herramientas de análisis estático o para agrupar acciones de CI en un mismo contenedor. Aquí hemos visto el uso de un único contenedor, pero es posible crear un entorno con varios contenedores a través de docker compose, el cual te animamos a que investigues en su documentación.

Comparte
Share on facebook
Share on twitter
Share on linkedin
¿Quieres más información?
Ponte en contacto con nosotros.
Jordi Mahiques
Jordi Mahiques
Backend developer - Departamento de desarrollo

Enviar Comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Artículos relacionados

Suscríbete a nuestra newsletter
para estar al día en el mundo online
¿Tienes alguna incidencia?

Cuéntanos qué ocurre
y nos pondremos con ello lo antes posible.

    Este sitio está protegido por reCAPTCHA, y la Política de privacidad y Términos de servicio de Google.
    ¡Cuéntanos tus ideas!
    +34 96 653 19 14
    info@acceseo.com

      Este sitio está protegido por reCAPTCHA, y la Política de privacidad y Términos de servicio de Google.